PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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 IsConflictLogTableClass (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 IsConflictLogTableNamespace (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 
)
extern

Definition at line 475 of file catalog.c.

476{
477 Oid newOid;
478 SysScanDesc scan;
480 bool collides;
481 uint64 retries = 0;
483
484 /* Only system relations are supported */
485 Assert(IsSystemRelation(relation));
486
487 /* In bootstrap mode, we don't have any indexes to use */
489 return GetNewObjectId();
490
491 /*
492 * We should never be asked to generate a new pg_type OID during
493 * pg_upgrade; doing so would risk collisions with the OIDs it wants to
494 * assign. Hitting this assert means there's some path where we failed to
495 * ensure that a type OID is determined by commands in the dump script.
496 */
498
499 /* Generate new OIDs until we find one not in the table */
500 do
501 {
503
505
506 ScanKeyInit(&key,
507 oidcolumn,
510
511 /* see notes above about using SnapshotAny */
512 scan = systable_beginscan(relation, indexId, true,
513 SnapshotAny, 1, &key);
514
516
517 systable_endscan(scan);
518
519 /*
520 * Log that we iterate more than GETNEWOID_LOG_THRESHOLD but have not
521 * yet found OID unused in the relation. Then repeat logging with
522 * exponentially increasing intervals until we iterate more than
523 * GETNEWOID_LOG_MAX_INTERVAL. Finally repeat logging every
524 * GETNEWOID_LOG_MAX_INTERVAL unless an unused OID is found. This
525 * logic is necessary not to fill up the server log with the similar
526 * messages.
527 */
528 if (retries >= retries_before_log)
529 {
530 ereport(LOG,
531 (errmsg("still searching for an unused OID in relation \"%s\"",
532 RelationGetRelationName(relation)),
533 errdetail_plural("OID candidates have been checked %" PRIu64 " time, but no unused OID has been found yet.",
534 "OID candidates have been checked %" PRIu64 " times, but no unused OID has been found yet.",
535 retries,
536 retries)));
537
538 /*
539 * Double the number of retries to do before logging next until it
540 * reaches GETNEWOID_LOG_MAX_INTERVAL.
541 */
544 else
546 }
547
548 retries++;
549 } while (collides);
550
551 /*
552 * If at least one log message is emitted, also log the completion of OID
553 * assignment.
554 */
555 if (retries > GETNEWOID_LOG_THRESHOLD)
556 {
557 ereport(LOG,
558 (errmsg_plural("new OID has been assigned in relation \"%s\" after %" PRIu64 " retry",
559 "new OID has been assigned in relation \"%s\" after %" PRIu64 " retries",
560 retries,
561 RelationGetRelationName(relation), retries)));
562 }
563
564 return newOid;
565}
#define Assert(condition)
Definition c.h:1002
uint64_t uint64
Definition c.h:684
#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
#define LOG
Definition elog.h:32
int int int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...) pg_attribute_printf(1
#define ereport(elevel,...)
Definition elog.h:152
int errdetail_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...) pg_attribute_printf(1
void systable_endscan(SysScanDesc sysscan)
Definition genam.c:604
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:515
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition genam.c:388
bool IsBinaryUpgrade
Definition globals.c:123
#define HeapTupleIsValid(tuple)
Definition htup.h:78
#define IsBootstrapProcessingMode()
Definition miscadmin.h:486
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:125
static char * errmsg
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
unsigned int Oid
static int fb(int x)
#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:554

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

Referenced by AddEnumLabel(), AddRoleMems(), AssignTypeArrayOid(), AssignTypeMultirangeArrayOid(), AssignTypeMultirangeOid(), CastCreate(), CollationCreate(), ConversionCreate(), copy_attribute_defaults(), copy_index_constraints(), CreateAccessMethod(), CreateConstraintEntry(), createdb(), CreateForeignDataWrapper(), CreateForeignServer(), CreateOpFamily(), CreatePolicy(), CreateProceduralLanguage(), CreatePublication(), CreateRole(), CreateStatistics(), CreateTableSpace(), CreateTransform(), CreateTriggerFiringOn(), CreateUserMapping(), DefineOpClass(), DefineTSConfiguration(), DefineTSDictionary(), DefineTSParser(), DefineTSTemplate(), EnumValuesCreate(), GetNewRelFileNumber(), insert_element_record(), insert_event_trigger_tuple(), insert_label_record(), insert_property_record(), 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 
)
extern

Definition at line 584 of file catalog.c.

585{
586 RelFileLocatorBackend rlocator;
587 RelPathStr rpath;
588 bool collides;
589 ProcNumber procNumber;
590
591 /*
592 * If we ever get here during pg_upgrade, there's something wrong; all
593 * relfilenumber assignments during a binary-upgrade run should be
594 * determined by commands in the dump script.
595 */
597
598 switch (relpersistence)
599 {
601 procNumber = ProcNumberForTempRelations();
602 break;
605 procNumber = INVALID_PROC_NUMBER;
606 break;
607 default:
608 elog(ERROR, "invalid relpersistence: %c", relpersistence);
609 return InvalidRelFileNumber; /* placate compiler */
610 }
611
612 /* This logic should match RelationInitPhysicalAddr */
613 rlocator.locator.spcOid = reltablespace ? reltablespace : MyDatabaseTableSpace;
614 rlocator.locator.dbOid =
615 (rlocator.locator.spcOid == GLOBALTABLESPACE_OID) ?
617
618 /*
619 * The relpath will vary based on the backend number, so we must
620 * initialize that properly here to make sure that any collisions based on
621 * filename are properly detected.
622 */
623 rlocator.backend = procNumber;
624
625 do
626 {
628
629 /* Generate the OID */
630 if (pg_class)
633 else
634 rlocator.locator.relNumber = GetNewObjectId();
635
636 /* Check for existing file of same name */
637 rpath = relpath(rlocator, MAIN_FORKNUM);
638
639 if (access(rpath.str, F_OK) == 0)
640 {
641 /* definite collision */
642 collides = true;
643 }
644 else
645 {
646 /*
647 * Here we have a little bit of a dilemma: if errno is something
648 * other than ENOENT, should we declare a collision and loop? In
649 * practice it seems best to go ahead regardless of the errno. If
650 * there is a colliding file we will get an smgr failure when we
651 * attempt to create the new relation file.
652 */
653 collides = false;
654 }
655 } while (collides);
656
657 return rlocator.locator.relNumber;
658}
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition catalog.c:475
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
Oid MyDatabaseTableSpace
Definition globals.c:98
Oid MyDatabaseId
Definition globals.c:96
#define InvalidOid
short access
#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, fb(), 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)
extern

Definition at line 259 of file catalog.c.

260{
262}

References fb().

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

◆ IsCatalogRelation()

◆ IsCatalogRelationOid()

bool IsCatalogRelationOid ( Oid  relid)
extern

Definition at line 123 of file catalog.c.

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

Definition at line 158 of file catalog.c.

159{
160 switch (relid)
161 {
166 return true;
167 }
168 return false;
169}

References fb().

Referenced by is_catalog_text_unique_index_oid().

◆ IsConflictLogTableClass()

◆ IsConflictLogTableNamespace()

◆ IsInplaceUpdateOid()

bool IsInplaceUpdateOid ( Oid  relid)
extern

Definition at line 195 of file catalog.c.

196{
197 return (relid == RelationRelationId ||
198 relid == DatabaseRelationId);
199}

References fb().

Referenced by IsInplaceUpdateRelation().

◆ IsInplaceUpdateRelation()

bool IsInplaceUpdateRelation ( Relation  relation)
extern

Definition at line 185 of file catalog.c.

186{
187 return IsInplaceUpdateOid(RelationGetRelid(relation));
188}
bool IsInplaceUpdateOid(Oid relid)
Definition catalog.c:195

References IsInplaceUpdateOid(), and RelationGetRelid.

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

◆ IsPinnedObject()

bool IsPinnedObject ( Oid  classId,
Oid  objectId 
)
extern

Definition at line 397 of file catalog.c.

398{
399 /*
400 * Objects with OIDs above FirstUnpinnedObjectId are never pinned. Since
401 * the OID generator skips this range when wrapping around, this check
402 * guarantees that user-defined objects are never considered pinned.
403 */
404 if (objectId >= FirstUnpinnedObjectId)
405 return false;
406
407 /*
408 * Large objects are never pinned. We need this special case because
409 * their OIDs can be user-assigned.
410 */
411 if (classId == LargeObjectRelationId)
412 return false;
413
414 /*
415 * There are a few objects defined in the catalog .dat files that, as a
416 * matter of policy, we prefer not to treat as pinned. We used to handle
417 * that by excluding them from pg_depend, but it's just as easy to
418 * hard-wire their OIDs here. (If the user does indeed drop and recreate
419 * them, they'll have new but certainly-unpinned OIDs, so no problem.)
420 *
421 * Checking both classId and objectId is overkill, since OIDs below
422 * FirstGenbkiObjectId should be globally unique, but do it anyway for
423 * robustness.
424 */
425
426 /* the public namespace is not pinned */
427 if (classId == NamespaceRelationId &&
428 objectId == PG_PUBLIC_NAMESPACE)
429 return false;
430
431 /*
432 * Databases are never pinned. It might seem that it'd be prudent to pin
433 * at least template0; but we do this intentionally so that template0 and
434 * template1 can be rebuilt from each other, thus letting them serve as
435 * mutual backups (as long as you've not modified template1, anyway).
436 */
437 if (classId == DatabaseRelationId)
438 return false;
439
440 /*
441 * All other initdb-created objects are pinned. This is overkill (the
442 * system doesn't really depend on having every last weird datatype, for
443 * instance) but generating only the minimum required set of dependencies
444 * seems hard, and enforcing an accurate list would be much more expensive
445 * than the simple range test used here.
446 */
447 return true;
448}

References fb(), and FirstUnpinnedObjectId.

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

◆ IsReservedName()

bool IsReservedName ( const char name)
extern

Definition at line 305 of file catalog.c.

306{
307 /* ugly coding for speed */
308 return (name[0] == 'p' &&
309 name[1] == 'g' &&
310 name[2] == '_');
311}
const char * name

References name.

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

◆ IsSharedRelation()

bool IsSharedRelation ( Oid  relationId)
extern

Definition at line 331 of file catalog.c.

332{
333 /* These are the shared catalogs (look for BKI_SHARED_RELATION) */
345 return true;
346 /* These are their indexes */
368 return true;
369 /* These are their toast tables and toast indexes */
384 return true;
385 return false;
386}

References fb().

Referenced by CacheInvalidateCatalog(), CacheInvalidateHeapTupleCommon(), classIdGetDbId(), DeleteSecurityLabel(), dependencyLockAndCheckObject(), findDependentObjects(), 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 
)
extern

◆ IsSystemRelation()

◆ IsToastClass()

bool IsToastClass ( Form_pg_class  reltuple)
extern

Definition at line 228 of file catalog.c.

229{
230 Oid relnamespace = reltuple->relnamespace;
231
232 return IsToastNamespace(relnamespace);
233}
bool IsToastNamespace(Oid namespaceId)
Definition catalog.c:277

References fb(), and IsToastNamespace().

Referenced by IsSystemClass().

◆ IsToastNamespace()

bool IsToastNamespace ( Oid  namespaceId)
extern

◆ IsToastRelation()

bool IsToastRelation ( Relation  relation)
extern

Definition at line 208 of file catalog.c.

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

References IsToastNamespace(), and RelationGetNamespace.

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