PostgreSQL Source Code git master
Loading...
Searching...
No Matches
catalog.c File Reference
#include "postgres.h"
#include <fcntl.h>
#include <unistd.h>
#include "access/genam.h"
#include "access/htup_details.h"
#include "access/table.h"
#include "access/transam.h"
#include "catalog/catalog.h"
#include "catalog/namespace.h"
#include "catalog/pg_auth_members.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_database.h"
#include "catalog/pg_db_role_setting.h"
#include "catalog/pg_largeobject.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_parameter_acl.h"
#include "catalog/pg_replication_origin.h"
#include "catalog/pg_seclabel.h"
#include "catalog/pg_shdepend.h"
#include "catalog/pg_shdescription.h"
#include "catalog/pg_shseclabel.h"
#include "catalog/pg_subscription.h"
#include "catalog/pg_tablespace.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
#include "utils/fmgroids.h"
#include "utils/fmgrprotos.h"
#include "utils/rel.h"
#include "utils/snapmgr.h"
#include "utils/syscache.h"
Include dependency graph for catalog.c:

Go to the source code of this file.

Macros

#define GETNEWOID_LOG_THRESHOLD   1000000
 
#define GETNEWOID_LOG_MAX_INTERVAL   128000000
 

Functions

bool IsSystemRelation (Relation relation)
 
bool IsSystemClass (Oid relid, Form_pg_class reltuple)
 
bool IsCatalogRelation (Relation relation)
 
bool IsCatalogRelationOid (Oid relid)
 
bool IsCatalogTextUniqueIndexOid (Oid relid)
 
bool IsInplaceUpdateRelation (Relation relation)
 
bool IsInplaceUpdateOid (Oid relid)
 
bool IsToastRelation (Relation relation)
 
bool IsToastClass (Form_pg_class reltuple)
 
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)
 
Datum pg_nextoid (PG_FUNCTION_ARGS)
 
Datum pg_stop_making_pinned_objects (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ GETNEWOID_LOG_MAX_INTERVAL

#define GETNEWOID_LOG_MAX_INTERVAL   128000000

Definition at line 56 of file catalog.c.

◆ GETNEWOID_LOG_THRESHOLD

#define GETNEWOID_LOG_THRESHOLD   1000000

Definition at line 55 of file catalog.c.

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

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)

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)

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 {
164 return true;
165 }
166 return false;
167}

References fb().

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}

References fb().

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 fb(), and 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_get_role_ddl_internal(), pg_get_tablespace_ddl_internal(), 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) */
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()

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

Referenced by IsSystemClass().

◆ IsToastNamespace()

bool IsToastNamespace ( Oid  namespaceId)

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

◆ pg_nextoid()

Datum pg_nextoid ( PG_FUNCTION_ARGS  )

Definition at line 641 of file catalog.c.

642{
643 Oid reloid = PG_GETARG_OID(0);
646 Relation rel;
650 AttrNumber attno;
651 Oid newoid;
652
653 /*
654 * As this function is not intended to be used during normal running, and
655 * only supports system catalogs (which require superuser permissions to
656 * modify), just checking for superuser ought to not obstruct valid
657 * usecases.
658 */
659 if (!superuser())
662 errmsg("must be superuser to call %s()",
663 "pg_nextoid")));
664
665 rel = table_open(reloid, RowExclusiveLock);
667
668 if (!IsSystemRelation(rel))
671 errmsg("pg_nextoid() can only be used on system catalogs")));
672
673 if (idx->rd_index->indrelid != RelationGetRelid(rel))
676 errmsg("index \"%s\" does not belong to table \"%s\"",
679
684 errmsg("column \"%s\" of relation \"%s\" does not exist",
686
688 attno = attform->attnum;
689
690 if (attform->atttypid != OIDOID)
693 errmsg("column \"%s\" is not of type oid",
694 NameStr(*attname))));
695
697 idx->rd_index->indkey.values[0] != attno)
700 errmsg("index \"%s\" is not the index for column \"%s\"",
702 NameStr(*attname))));
703
704 newoid = GetNewOidWithIndex(rel, idxoid, attno);
705
709
711}
Datum idx(PG_FUNCTION_ARGS)
Definition _int_op.c:262
int16 AttrNumber
Definition attnum.h:21
#define NameStr(name)
Definition c.h:835
int errcode(int sqlerrcode)
Definition elog.c:874
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define PG_GETARG_NAME(n)
Definition fmgr.h:279
#define PG_RETURN_OID(x)
Definition fmgr.h:361
static void * GETSTRUCT(const HeapTupleData *tuple)
void index_close(Relation relation, LOCKMODE lockmode)
Definition indexam.c:178
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition indexam.c:134
#define RowExclusiveLock
Definition lockdefs.h:38
NameData attname
FormData_pg_attribute * Form_pg_attribute
#define IndexRelationGetNumberOfKeyAttributes(relation)
Definition rel.h:535
Definition c.h:830
bool superuser(void)
Definition superuser.c:47
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:265
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition syscache.c:476
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40

References attname, ereport, errcode(), errmsg, ERROR, fb(), GetNewOidWithIndex(), GETSTRUCT(), HeapTupleIsValid, idx(), index_close(), index_open(), IndexRelationGetNumberOfKeyAttributes, IsSystemRelation(), NameStr, PG_GETARG_NAME, PG_GETARG_OID, PG_RETURN_OID, RelationGetRelationName, RelationGetRelid, ReleaseSysCache(), RowExclusiveLock, SearchSysCacheAttName(), superuser(), table_close(), and table_open().

◆ pg_stop_making_pinned_objects()

Datum pg_stop_making_pinned_objects ( PG_FUNCTION_ARGS  )

Definition at line 720 of file catalog.c.

721{
722 /*
723 * Belt-and-suspenders check, since StopGeneratingPinnedObjectIds will
724 * fail anyway in non-single-user mode.
725 */
726 if (!superuser())
729 errmsg("must be superuser to call %s()",
730 "pg_stop_making_pinned_objects")));
731
733
735}
#define PG_RETURN_VOID()
Definition fmgr.h:350
void StopGeneratingPinnedObjectIds(void)
Definition varsup.c:651

References ereport, errcode(), errmsg, ERROR, fb(), PG_RETURN_VOID, StopGeneratingPinnedObjectIds(), and superuser().