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:873
uint64_t uint64
Definition c.h:547
#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:1193
int errdetail_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition elog.c:1308
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define LOG
Definition elog.h:31
#define ereport(elevel,...)
Definition elog.h:150
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:121
#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:262
unsigned int Oid
static int fb(int x)
#define RelationGetRelid(relation)
Definition rel.h:514
#define RelationGetRelationName(relation)
Definition rel.h:548
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(), 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(), 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 {
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:39
#define elog(elevel,...)
Definition elog.h:226
Oid MyDatabaseTableSpace
Definition globals.c:96
Oid MyDatabaseId
Definition globals.c:94
#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_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(), 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:555

References IsToastNamespace(), and RelationGetNamespace.

Referenced by CacheInvalidateHeapTupleCommon(), 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:765
int errcode(int sqlerrcode)
Definition elog.c:863
#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:177
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition indexam.c:133
#define RowExclusiveLock
Definition lockdefs.h:38
NameData attname
FormData_pg_attribute * Form_pg_attribute
#define IndexRelationGetNumberOfKeyAttributes(relation)
Definition rel.h:533
Definition c.h:760
bool superuser(void)
Definition superuser.c:46
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition syscache.c:475
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:652

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