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 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 
)
extern

Definition at line 448 of file catalog.c.

449{
450 Oid newOid;
451 SysScanDesc scan;
453 bool collides;
454 uint64 retries = 0;
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 */
471
472 /* Generate new OIDs until we find one not in the table */
473 do
474 {
476
478
479 ScanKeyInit(&key,
480 oidcolumn,
483
484 /* see notes above about using SnapshotAny */
485 scan = systable_beginscan(relation, indexId, true,
486 SnapshotAny, 1, &key);
487
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 */
517 else
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}
#define Assert(condition)
Definition c.h:943
uint64_t uint64
Definition c.h:625
#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:612
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:523
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:495
#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_index_constraints(), CreateAccessMethod(), CreateConstraintEntry(), createdb(), CreateForeignDataWrapper(), CreateForeignServer(), CreateOpFamily(), CreatePolicy(), CreateProceduralLanguage(), CreatePublication(), CreateRole(), CreateStatistics(), CreateSubscription(), 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 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 {
574 procNumber = ProcNumberForTempRelations();
575 break;
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)
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: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 243 of file catalog.c.

244{
246}

References fb().

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

◆ IsCatalogRelation()

◆ IsCatalogRelationOid()

bool IsCatalogRelationOid ( Oid  relid)
extern

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)
extern

Definition at line 156 of file catalog.c.

157{
158 switch (relid)
159 {
164 return true;
165 }
166 return false;
167}

References fb().

Referenced by is_catalog_text_unique_index_oid().

◆ IsInplaceUpdateOid()

bool IsInplaceUpdateOid ( Oid  relid)
extern

Definition at line 193 of file catalog.c.

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

References fb().

Referenced by IsInplaceUpdateRelation().

◆ IsInplaceUpdateRelation()

bool IsInplaceUpdateRelation ( Relation  relation)
extern

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 
)
extern

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 fb(), and FirstUnpinnedObjectId.

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

◆ IsReservedName()

bool IsReservedName ( const char name)
extern

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_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 304 of file catalog.c.

305{
306 /* These are the shared catalogs (look for BKI_SHARED_RELATION) */
318 return true;
319 /* These are their indexes */
341 return true;
342 /* These are their toast tables and toast indexes */
357 return true;
358 return false;
359}

References fb().

Referenced by CacheInvalidateCatalog(), CacheInvalidateHeapTupleCommon(), classIdGetDbId(), DeleteSecurityLabel(), 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 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 fb(), and IsToastNamespace().

Referenced by IsSystemClass().

◆ IsToastNamespace()

bool IsToastNamespace ( Oid  namespaceId)
extern

◆ IsToastRelation()

bool IsToastRelation ( Relation  relation)
extern

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(), check_concurrent_repack_requirements(), heap_abort_speculative(), heap_insert(), ReorderBufferProcessTXN(), and ReorderBufferToastAppendChunk().