PostgreSQL Source Code git master
catalog.h File Reference
#include "catalog/pg_class.h"
#include "utils/relcache.h"
Include dependency graph for catalog.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

bool IsSystemRelation (Relation relation)
 
bool IsToastRelation (Relation relation)
 
bool IsCatalogRelation (Relation relation)
 
bool IsInplaceUpdateRelation (Relation relation)
 
bool IsSystemClass (Oid relid, Form_pg_class reltuple)
 
bool IsToastClass (Form_pg_class reltuple)
 
bool IsCatalogRelationOid (Oid relid)
 
bool IsCatalogTextUniqueIndexOid (Oid relid)
 
bool IsInplaceUpdateOid (Oid relid)
 
bool IsCatalogNamespace (Oid namespaceId)
 
bool IsToastNamespace (Oid namespaceId)
 
bool IsReservedName (const char *name)
 
bool IsSharedRelation (Oid relationId)
 
bool IsPinnedObject (Oid classId, Oid objectId)
 
Oid GetNewOidWithIndex (Relation relation, Oid indexId, AttrNumber oidcolumn)
 
RelFileNumber GetNewRelFileNumber (Oid reltablespace, Relation pg_class, char relpersistence)
 

Function Documentation

◆ GetNewOidWithIndex()

Oid GetNewOidWithIndex ( Relation  relation,
Oid  indexId,
AttrNumber  oidcolumn 
)

Definition at line 448 of file catalog.c.

449{
450 Oid newOid;
451 SysScanDesc scan;
453 bool collides;
454 uint64 retries = 0;
455 uint64 retries_before_log = GETNEWOID_LOG_THRESHOLD;
456
457 /* Only system relations are supported */
458 Assert(IsSystemRelation(relation));
459
460 /* In bootstrap mode, we don't have any indexes to use */
462 return GetNewObjectId();
463
464 /*
465 * We should never be asked to generate a new pg_type OID during
466 * pg_upgrade; doing so would risk collisions with the OIDs it wants to
467 * assign. Hitting this assert means there's some path where we failed to
468 * ensure that a type OID is determined by commands in the dump script.
469 */
470 Assert(!IsBinaryUpgrade || RelationGetRelid(relation) != TypeRelationId);
471
472 /* Generate new OIDs until we find one not in the table */
473 do
474 {
476
477 newOid = GetNewObjectId();
478
480 oidcolumn,
481 BTEqualStrategyNumber, F_OIDEQ,
482 ObjectIdGetDatum(newOid));
483
484 /* see notes above about using SnapshotAny */
485 scan = systable_beginscan(relation, indexId, true,
486 SnapshotAny, 1, &key);
487
488 collides = HeapTupleIsValid(systable_getnext(scan));
489
490 systable_endscan(scan);
491
492 /*
493 * Log that we iterate more than GETNEWOID_LOG_THRESHOLD but have not
494 * yet found OID unused in the relation. Then repeat logging with
495 * exponentially increasing intervals until we iterate more than
496 * GETNEWOID_LOG_MAX_INTERVAL. Finally repeat logging every
497 * GETNEWOID_LOG_MAX_INTERVAL unless an unused OID is found. This
498 * logic is necessary not to fill up the server log with the similar
499 * messages.
500 */
501 if (retries >= retries_before_log)
502 {
503 ereport(LOG,
504 (errmsg("still searching for an unused OID in relation \"%s\"",
505 RelationGetRelationName(relation)),
506 errdetail_plural("OID candidates have been checked %" PRIu64 " time, but no unused OID has been found yet.",
507 "OID candidates have been checked %" PRIu64 " times, but no unused OID has been found yet.",
508 retries,
509 retries)));
510
511 /*
512 * Double the number of retries to do before logging next until it
513 * reaches GETNEWOID_LOG_MAX_INTERVAL.
514 */
515 if (retries_before_log * 2 <= GETNEWOID_LOG_MAX_INTERVAL)
516 retries_before_log *= 2;
517 else
518 retries_before_log += GETNEWOID_LOG_MAX_INTERVAL;
519 }
520
521 retries++;
522 } while (collides);
523
524 /*
525 * If at least one log message is emitted, also log the completion of OID
526 * assignment.
527 */
528 if (retries > GETNEWOID_LOG_THRESHOLD)
529 {
530 ereport(LOG,
531 (errmsg_plural("new OID has been assigned in relation \"%s\" after %" PRIu64 " retry",
532 "new OID has been assigned in relation \"%s\" after %" PRIu64 " retries",
533 retries,
534 RelationGetRelationName(relation), retries)));
535 }
536
537 return newOid;
538}
uint64_t uint64
Definition: c.h:503
#define GETNEWOID_LOG_THRESHOLD
Definition: catalog.c:55
bool IsSystemRelation(Relation relation)
Definition: catalog.c:74
#define GETNEWOID_LOG_MAX_INTERVAL
Definition: catalog.c:56
int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:1181
int errdetail_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:1296
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define LOG
Definition: elog.h:31
#define ereport(elevel,...)
Definition: elog.h:149
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:603
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:514
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:388
bool IsBinaryUpgrade
Definition: globals.c:122
Assert(PointerIsAligned(start, uint64))
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:477
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:123
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
unsigned int Oid
Definition: postgres_ext.h:30
#define RelationGetRelid(relation)
Definition: rel.h:516
#define RelationGetRelationName(relation)
Definition: rel.h:550
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define SnapshotAny
Definition: snapmgr.h:33
#define BTEqualStrategyNumber
Definition: stratnum.h:31
Oid GetNewObjectId(void)
Definition: varsup.c:555

References Assert(), BTEqualStrategyNumber, CHECK_FOR_INTERRUPTS, ereport, errdetail_plural(), errmsg(), errmsg_plural(), GetNewObjectId(), GETNEWOID_LOG_MAX_INTERVAL, GETNEWOID_LOG_THRESHOLD, HeapTupleIsValid, IsBinaryUpgrade, IsBootstrapProcessingMode, IsSystemRelation(), sort-test::key, LOG, ObjectIdGetDatum(), RelationGetRelationName, RelationGetRelid, ScanKeyInit(), SnapshotAny, systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by AddEnumLabel(), AddRoleMems(), AssignTypeArrayOid(), AssignTypeMultirangeArrayOid(), AssignTypeMultirangeOid(), CastCreate(), CollationCreate(), ConversionCreate(), CreateAccessMethod(), CreateConstraintEntry(), createdb(), CreateForeignDataWrapper(), CreateForeignServer(), CreateOpFamily(), CreatePolicy(), CreateProceduralLanguage(), CreatePublication(), CreateRole(), CreateStatistics(), CreateSubscription(), CreateTableSpace(), CreateTransform(), CreateTriggerFiringOn(), CreateUserMapping(), DefineOpClass(), DefineTSConfiguration(), DefineTSDictionary(), DefineTSParser(), DefineTSTemplate(), EnumValuesCreate(), GetNewRelFileNumber(), insert_event_trigger_tuple(), InsertExtensionTuple(), InsertRule(), LargeObjectCreate(), NamespaceCreate(), OperatorCreate(), OperatorShellMake(), ParameterAclCreate(), pg_nextoid(), ProcedureCreate(), publication_add_relation(), publication_add_schema(), SetDefaultACL(), StoreAttrDefault(), storeOperators(), storeProcedures(), toast_save_datum(), TypeCreate(), and TypeShellMake().

◆ GetNewRelFileNumber()

RelFileNumber GetNewRelFileNumber ( Oid  reltablespace,
Relation  pg_class,
char  relpersistence 
)

Definition at line 557 of file catalog.c.

558{
559 RelFileLocatorBackend rlocator;
560 RelPathStr rpath;
561 bool collides;
562 ProcNumber procNumber;
563
564 /*
565 * If we ever get here during pg_upgrade, there's something wrong; all
566 * relfilenumber assignments during a binary-upgrade run should be
567 * determined by commands in the dump script.
568 */
570
571 switch (relpersistence)
572 {
573 case RELPERSISTENCE_TEMP:
574 procNumber = ProcNumberForTempRelations();
575 break;
576 case RELPERSISTENCE_UNLOGGED:
577 case RELPERSISTENCE_PERMANENT:
578 procNumber = INVALID_PROC_NUMBER;
579 break;
580 default:
581 elog(ERROR, "invalid relpersistence: %c", relpersistence);
582 return InvalidRelFileNumber; /* placate compiler */
583 }
584
585 /* This logic should match RelationInitPhysicalAddr */
586 rlocator.locator.spcOid = reltablespace ? reltablespace : MyDatabaseTableSpace;
587 rlocator.locator.dbOid =
588 (rlocator.locator.spcOid == GLOBALTABLESPACE_OID) ?
590
591 /*
592 * The relpath will vary based on the backend number, so we must
593 * initialize that properly here to make sure that any collisions based on
594 * filename are properly detected.
595 */
596 rlocator.backend = procNumber;
597
598 do
599 {
601
602 /* Generate the OID */
603 if (pg_class)
604 rlocator.locator.relNumber = GetNewOidWithIndex(pg_class, ClassOidIndexId,
605 Anum_pg_class_oid);
606 else
607 rlocator.locator.relNumber = GetNewObjectId();
608
609 /* Check for existing file of same name */
610 rpath = relpath(rlocator, MAIN_FORKNUM);
611
612 if (access(rpath.str, F_OK) == 0)
613 {
614 /* definite collision */
615 collides = true;
616 }
617 else
618 {
619 /*
620 * Here we have a little bit of a dilemma: if errno is something
621 * other than ENOENT, should we declare a collision and loop? In
622 * practice it seems best to go ahead regardless of the errno. If
623 * there is a colliding file we will get an smgr failure when we
624 * attempt to create the new relation file.
625 */
626 collides = false;
627 }
628 } while (collides);
629
630 return rlocator.locator.relNumber;
631}
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:448
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
Oid MyDatabaseTableSpace
Definition: globals.c:97
Oid MyDatabaseId
Definition: globals.c:95
#define InvalidOid
Definition: postgres_ext.h:35
short access
Definition: preproc-type.c:36
#define INVALID_PROC_NUMBER
Definition: procnumber.h:26
int ProcNumber
Definition: procnumber.h:24
#define ProcNumberForTempRelations()
Definition: procnumber.h:53
@ MAIN_FORKNUM
Definition: relpath.h:58
#define relpath(rlocator, forknum)
Definition: relpath.h:150
#define InvalidRelFileNumber
Definition: relpath.h:26
RelFileLocator locator
RelFileNumber relNumber
char str[REL_PATH_STR_MAXLEN+1]
Definition: relpath.h:123

References Assert(), RelFileLocatorBackend::backend, CHECK_FOR_INTERRUPTS, RelFileLocator::dbOid, elog, ERROR, GetNewObjectId(), GetNewOidWithIndex(), INVALID_PROC_NUMBER, InvalidOid, InvalidRelFileNumber, IsBinaryUpgrade, RelFileLocatorBackend::locator, MAIN_FORKNUM, MyDatabaseId, MyDatabaseTableSpace, ProcNumberForTempRelations, RelFileLocator::relNumber, relpath, RelFileLocator::spcOid, and RelPathStr::str.

Referenced by ATExecSetTableSpace(), heap_create_with_catalog(), index_create(), and RelationSetNewRelfilenumber().

◆ IsCatalogNamespace()

bool IsCatalogNamespace ( Oid  namespaceId)

Definition at line 243 of file catalog.c.

244{
245 return namespaceId == PG_CATALOG_NAMESPACE;
246}

Referenced by AlterTableMoveAll(), check_publication_add_schema(), heap_create(), and RelationBuildLocalRelation().

◆ IsCatalogRelation()

◆ IsCatalogRelationOid()

bool IsCatalogRelationOid ( Oid  relid)

Definition at line 121 of file catalog.c.

122{
123 /*
124 * We consider a relation to be a system catalog if it has a pinned OID.
125 * This includes all the defined catalogs, their indexes, and their TOAST
126 * tables and indexes.
127 *
128 * This rule excludes the relations in information_schema, which are not
129 * integral to the system and can be treated the same as user relations.
130 * (Since it's valid to drop and recreate information_schema, any rule
131 * that did not act this way would be wrong.)
132 *
133 * This test is reliable since an OID wraparound will skip this range of
134 * OIDs; see GetNewObjectId().
135 */
136 return (relid < (Oid) FirstUnpinnedObjectId);
137}
#define FirstUnpinnedObjectId
Definition: transam.h:196

References FirstUnpinnedObjectId.

Referenced by check_relation_privileges(), is_publishable_class(), IsCatalogRelation(), IsSystemClass(), populate_compact_attribute_internal(), read_stream_begin_impl(), ReindexMultipleTables(), and ReindexRelationConcurrently().

◆ IsCatalogTextUniqueIndexOid()

bool IsCatalogTextUniqueIndexOid ( Oid  relid)

Definition at line 156 of file catalog.c.

157{
158 switch (relid)
159 {
160 case ParameterAclParnameIndexId:
161 case ReplicationOriginNameIndex:
162 case SecLabelObjectIndexId:
163 case SharedSecLabelObjectIndexId:
164 return true;
165 }
166 return false;
167}

Referenced by is_catalog_text_unique_index_oid().

◆ IsInplaceUpdateOid()

bool IsInplaceUpdateOid ( Oid  relid)

Definition at line 193 of file catalog.c.

194{
195 return (relid == RelationRelationId ||
196 relid == DatabaseRelationId);
197}

Referenced by IsInplaceUpdateRelation().

◆ IsInplaceUpdateRelation()

bool IsInplaceUpdateRelation ( Relation  relation)

Definition at line 183 of file catalog.c.

184{
185 return IsInplaceUpdateOid(RelationGetRelid(relation));
186}
bool IsInplaceUpdateOid(Oid relid)
Definition: catalog.c:193

References IsInplaceUpdateOid(), and RelationGetRelid.

Referenced by CheckValidResultRel(), InitResultRelInfo(), and systable_inplace_update_begin().

◆ IsPinnedObject()

bool IsPinnedObject ( Oid  classId,
Oid  objectId 
)

Definition at line 370 of file catalog.c.

371{
372 /*
373 * Objects with OIDs above FirstUnpinnedObjectId are never pinned. Since
374 * the OID generator skips this range when wrapping around, this check
375 * guarantees that user-defined objects are never considered pinned.
376 */
377 if (objectId >= FirstUnpinnedObjectId)
378 return false;
379
380 /*
381 * Large objects are never pinned. We need this special case because
382 * their OIDs can be user-assigned.
383 */
384 if (classId == LargeObjectRelationId)
385 return false;
386
387 /*
388 * There are a few objects defined in the catalog .dat files that, as a
389 * matter of policy, we prefer not to treat as pinned. We used to handle
390 * that by excluding them from pg_depend, but it's just as easy to
391 * hard-wire their OIDs here. (If the user does indeed drop and recreate
392 * them, they'll have new but certainly-unpinned OIDs, so no problem.)
393 *
394 * Checking both classId and objectId is overkill, since OIDs below
395 * FirstGenbkiObjectId should be globally unique, but do it anyway for
396 * robustness.
397 */
398
399 /* the public namespace is not pinned */
400 if (classId == NamespaceRelationId &&
401 objectId == PG_PUBLIC_NAMESPACE)
402 return false;
403
404 /*
405 * Databases are never pinned. It might seem that it'd be prudent to pin
406 * at least template0; but we do this intentionally so that template0 and
407 * template1 can be rebuilt from each other, thus letting them serve as
408 * mutual backups (as long as you've not modified template1, anyway).
409 */
410 if (classId == DatabaseRelationId)
411 return false;
412
413 /*
414 * All other initdb-created objects are pinned. This is overkill (the
415 * system doesn't really depend on having every last weird datatype, for
416 * instance) but generating only the minimum required set of dependencies
417 * seems hard, and enforcing an accurate list would be much more expensive
418 * than the simple range test used here.
419 */
420 return true;
421}

References FirstUnpinnedObjectId.

Referenced by checkSharedDependencies(), DropTableSpace(), findDependentObjects(), isObjectPinned(), recordSharedDependencyOn(), shdepChangeDep(), shdepDropOwned(), shdepReassignOwned(), typeDepNeeded(), and updateAclDependenciesWorker().

◆ IsReservedName()

bool IsReservedName ( const char *  name)

Definition at line 278 of file catalog.c.

279{
280 /* ugly coding for speed */
281 return (name[0] == 'p' &&
282 name[1] == 'g' &&
283 name[2] == '_');
284}
const char * name

References name.

Referenced by check_rolespec_name(), CreateRole(), CreateSchemaCommand(), CreateTableSpace(), pg_replication_origin_create(), RenameRole(), RenameSchema(), and RenameTableSpace().

◆ IsSharedRelation()

bool IsSharedRelation ( Oid  relationId)

Definition at line 304 of file catalog.c.

305{
306 /* These are the shared catalogs (look for BKI_SHARED_RELATION) */
307 if (relationId == AuthIdRelationId ||
308 relationId == AuthMemRelationId ||
309 relationId == DatabaseRelationId ||
310 relationId == DbRoleSettingRelationId ||
311 relationId == ParameterAclRelationId ||
312 relationId == ReplicationOriginRelationId ||
313 relationId == SharedDependRelationId ||
314 relationId == SharedDescriptionRelationId ||
315 relationId == SharedSecLabelRelationId ||
316 relationId == SubscriptionRelationId ||
317 relationId == TableSpaceRelationId)
318 return true;
319 /* These are their indexes */
320 if (relationId == AuthIdOidIndexId ||
321 relationId == AuthIdRolnameIndexId ||
322 relationId == AuthMemMemRoleIndexId ||
323 relationId == AuthMemRoleMemIndexId ||
324 relationId == AuthMemOidIndexId ||
325 relationId == AuthMemGrantorIndexId ||
326 relationId == DatabaseNameIndexId ||
327 relationId == DatabaseOidIndexId ||
328 relationId == DbRoleSettingDatidRolidIndexId ||
329 relationId == ParameterAclOidIndexId ||
330 relationId == ParameterAclParnameIndexId ||
331 relationId == ReplicationOriginIdentIndex ||
332 relationId == ReplicationOriginNameIndex ||
333 relationId == SharedDependDependerIndexId ||
334 relationId == SharedDependReferenceIndexId ||
335 relationId == SharedDescriptionObjIndexId ||
336 relationId == SharedSecLabelObjectIndexId ||
337 relationId == SubscriptionNameIndexId ||
338 relationId == SubscriptionObjectIndexId ||
339 relationId == TablespaceNameIndexId ||
340 relationId == TablespaceOidIndexId)
341 return true;
342 /* These are their toast tables and toast indexes */
343 if (relationId == PgDatabaseToastTable ||
344 relationId == PgDatabaseToastIndex ||
345 relationId == PgDbRoleSettingToastTable ||
346 relationId == PgDbRoleSettingToastIndex ||
347 relationId == PgParameterAclToastTable ||
348 relationId == PgParameterAclToastIndex ||
349 relationId == PgShdescriptionToastTable ||
350 relationId == PgShdescriptionToastIndex ||
351 relationId == PgShseclabelToastTable ||
352 relationId == PgShseclabelToastIndex ||
353 relationId == PgSubscriptionToastTable ||
354 relationId == PgSubscriptionToastIndex ||
355 relationId == PgTablespaceToastTable ||
356 relationId == PgTablespaceToastIndex)
357 return true;
358 return false;
359}

Referenced by CacheInvalidateCatalog(), CacheInvalidateHeapTupleCommon(), classIdGetDbId(), DeleteSecurityLabel(), get_object_address(), GetSecurityLabel(), pg_stat_reset_single_table_counters(), pgstat_fetch_stat_tabentry(), RelationBuildLocalRelation(), SetLocktagRelationOid(), SetSecurityLabel(), and UpdateLogicalMappings().

◆ IsSystemClass()

bool IsSystemClass ( Oid  relid,
Form_pg_class  reltuple 
)

◆ IsSystemRelation()

◆ IsToastClass()

bool IsToastClass ( Form_pg_class  reltuple)

Definition at line 226 of file catalog.c.

227{
228 Oid relnamespace = reltuple->relnamespace;
229
230 return IsToastNamespace(relnamespace);
231}
bool IsToastNamespace(Oid namespaceId)
Definition: catalog.c:261

References IsToastNamespace().

Referenced by IsSystemClass().

◆ IsToastNamespace()

bool IsToastNamespace ( Oid  namespaceId)

Definition at line 261 of file catalog.c.

262{
263 return (namespaceId == PG_TOAST_NAMESPACE) ||
264 isTempToastNamespace(namespaceId);
265}
bool isTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3661

References isTempToastNamespace().

Referenced by AlterTableMoveAll(), check_publication_add_schema(), heap_create(), IsToastClass(), IsToastRelation(), reindex_index(), reindex_relation(), and ReindexRelationConcurrently().

◆ IsToastRelation()

bool IsToastRelation ( Relation  relation)

Definition at line 206 of file catalog.c.

207{
208 /*
209 * What we actually check is whether the relation belongs to a pg_toast
210 * namespace. This should be equivalent because of restrictions that are
211 * enforced elsewhere against creating user relations in, or moving
212 * relations into/out of, a pg_toast namespace. Notice also that this
213 * will not say "true" for toast tables belonging to other sessions' temp
214 * tables; we expect that other mechanisms will prevent access to those.
215 */
216 return IsToastNamespace(RelationGetNamespace(relation));
217}
#define RelationGetNamespace(relation)
Definition: rel.h:557

References IsToastNamespace(), and RelationGetNamespace.

Referenced by CacheInvalidateHeapTupleCommon(), heap_abort_speculative(), heap_insert(), ReorderBufferProcessTXN(), and ReorderBufferToastAppendChunk().