PostgreSQL Source Code  git master
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_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 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 55 of file catalog.c.

◆ GETNEWOID_LOG_THRESHOLD

#define GETNEWOID_LOG_THRESHOLD   1000000

Definition at line 54 of file catalog.c.

Function Documentation

◆ GetNewOidWithIndex()

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

Definition at line 419 of file catalog.c.

420 {
421  Oid newOid;
422  SysScanDesc scan;
424  bool collides;
425  uint64 retries = 0;
426  uint64 retries_before_log = GETNEWOID_LOG_THRESHOLD;
427 
428  /* Only system relations are supported */
429  Assert(IsSystemRelation(relation));
430 
431  /* In bootstrap mode, we don't have any indexes to use */
433  return GetNewObjectId();
434 
435  /*
436  * We should never be asked to generate a new pg_type OID during
437  * pg_upgrade; doing so would risk collisions with the OIDs it wants to
438  * assign. Hitting this assert means there's some path where we failed to
439  * ensure that a type OID is determined by commands in the dump script.
440  */
441  Assert(!IsBinaryUpgrade || RelationGetRelid(relation) != TypeRelationId);
442 
443  /* Generate new OIDs until we find one not in the table */
444  do
445  {
447 
448  newOid = GetNewObjectId();
449 
450  ScanKeyInit(&key,
451  oidcolumn,
452  BTEqualStrategyNumber, F_OIDEQ,
453  ObjectIdGetDatum(newOid));
454 
455  /* see notes above about using SnapshotAny */
456  scan = systable_beginscan(relation, indexId, true,
457  SnapshotAny, 1, &key);
458 
459  collides = HeapTupleIsValid(systable_getnext(scan));
460 
461  systable_endscan(scan);
462 
463  /*
464  * Log that we iterate more than GETNEWOID_LOG_THRESHOLD but have not
465  * yet found OID unused in the relation. Then repeat logging with
466  * exponentially increasing intervals until we iterate more than
467  * GETNEWOID_LOG_MAX_INTERVAL. Finally repeat logging every
468  * GETNEWOID_LOG_MAX_INTERVAL unless an unused OID is found. This
469  * logic is necessary not to fill up the server log with the similar
470  * messages.
471  */
472  if (retries >= retries_before_log)
473  {
474  ereport(LOG,
475  (errmsg("still searching for an unused OID in relation \"%s\"",
476  RelationGetRelationName(relation)),
477  errdetail_plural("OID candidates have been checked %llu time, but no unused OID has been found yet.",
478  "OID candidates have been checked %llu times, but no unused OID has been found yet.",
479  retries,
480  (unsigned long long) retries)));
481 
482  /*
483  * Double the number of retries to do before logging next until it
484  * reaches GETNEWOID_LOG_MAX_INTERVAL.
485  */
486  if (retries_before_log * 2 <= GETNEWOID_LOG_MAX_INTERVAL)
487  retries_before_log *= 2;
488  else
489  retries_before_log += GETNEWOID_LOG_MAX_INTERVAL;
490  }
491 
492  retries++;
493  } while (collides);
494 
495  /*
496  * If at least one log message is emitted, also log the completion of OID
497  * assignment.
498  */
499  if (retries > GETNEWOID_LOG_THRESHOLD)
500  {
501  ereport(LOG,
502  (errmsg_plural("new OID has been assigned in relation \"%s\" after %llu retry",
503  "new OID has been assigned in relation \"%s\" after %llu retries",
504  retries,
505  RelationGetRelationName(relation), (unsigned long long) retries)));
506  }
507 
508  return newOid;
509 }
#define Assert(condition)
Definition: c.h:849
#define GETNEWOID_LOG_THRESHOLD
Definition: catalog.c:54
bool IsSystemRelation(Relation relation)
Definition: catalog.c:73
#define GETNEWOID_LOG_MAX_INTERVAL
Definition: catalog.c:55
int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:1180
int errdetail_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:1295
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define LOG
Definition: elog.h:31
#define ereport(elevel,...)
Definition: elog.h:149
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:604
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:511
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:387
bool IsBinaryUpgrade
Definition: globals.c:120
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:451
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
unsigned int Oid
Definition: postgres_ext.h:31
#define RelationGetRelid(relation)
Definition: rel.h:505
#define RelationGetRelationName(relation)
Definition: rel.h:539
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 528 of file catalog.c.

529 {
530  RelFileLocatorBackend rlocator;
531  char *rpath;
532  bool collides;
533  ProcNumber procNumber;
534 
535  /*
536  * If we ever get here during pg_upgrade, there's something wrong; all
537  * relfilenumber assignments during a binary-upgrade run should be
538  * determined by commands in the dump script.
539  */
541 
542  switch (relpersistence)
543  {
544  case RELPERSISTENCE_TEMP:
545  procNumber = ProcNumberForTempRelations();
546  break;
547  case RELPERSISTENCE_UNLOGGED:
548  case RELPERSISTENCE_PERMANENT:
549  procNumber = INVALID_PROC_NUMBER;
550  break;
551  default:
552  elog(ERROR, "invalid relpersistence: %c", relpersistence);
553  return InvalidRelFileNumber; /* placate compiler */
554  }
555 
556  /* This logic should match RelationInitPhysicalAddr */
557  rlocator.locator.spcOid = reltablespace ? reltablespace : MyDatabaseTableSpace;
558  rlocator.locator.dbOid =
559  (rlocator.locator.spcOid == GLOBALTABLESPACE_OID) ?
561 
562  /*
563  * The relpath will vary based on the backend number, so we must
564  * initialize that properly here to make sure that any collisions based on
565  * filename are properly detected.
566  */
567  rlocator.backend = procNumber;
568 
569  do
570  {
572 
573  /* Generate the OID */
574  if (pg_class)
575  rlocator.locator.relNumber = GetNewOidWithIndex(pg_class, ClassOidIndexId,
576  Anum_pg_class_oid);
577  else
578  rlocator.locator.relNumber = GetNewObjectId();
579 
580  /* Check for existing file of same name */
581  rpath = relpath(rlocator, MAIN_FORKNUM);
582 
583  if (access(rpath, F_OK) == 0)
584  {
585  /* definite collision */
586  collides = true;
587  }
588  else
589  {
590  /*
591  * Here we have a little bit of a dilemma: if errno is something
592  * other than ENOENT, should we declare a collision and loop? In
593  * practice it seems best to go ahead regardless of the errno. If
594  * there is a colliding file we will get an smgr failure when we
595  * attempt to create the new relation file.
596  */
597  collides = false;
598  }
599 
600  pfree(rpath);
601  } while (collides);
602 
603  return rlocator.locator.relNumber;
604 }
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:419
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
Oid MyDatabaseTableSpace
Definition: globals.c:95
Oid MyDatabaseId
Definition: globals.c:93
void pfree(void *pointer)
Definition: mcxt.c:1521
#define InvalidOid
Definition: postgres_ext.h:36
short access
Definition: preproc-type.c:36
#define ProcNumberForTempRelations()
Definition: proc.h:324
#define INVALID_PROC_NUMBER
Definition: procnumber.h:26
int ProcNumber
Definition: procnumber.h:24
@ MAIN_FORKNUM
Definition: relpath.h:58
#define relpath(rlocator, forknum)
Definition: relpath.h:102
#define InvalidRelFileNumber
Definition: relpath.h:26
RelFileLocator locator
RelFileNumber relNumber

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, pfree(), ProcNumberForTempRelations, RelFileLocator::relNumber, relpath, and RelFileLocator::spcOid.

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

◆ IsCatalogNamespace()

bool IsCatalogNamespace ( Oid  namespaceId)

Definition at line 212 of file catalog.c.

213 {
214  return namespaceId == PG_CATALOG_NAMESPACE;
215 }

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

◆ IsCatalogRelation()

◆ IsCatalogRelationOid()

bool IsCatalogRelationOid ( Oid  relid)

Definition at line 120 of file catalog.c.

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

References FirstUnpinnedObjectId.

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

◆ IsInplaceUpdateOid()

bool IsInplaceUpdateOid ( Oid  relid)

Definition at line 162 of file catalog.c.

163 {
164  return (relid == RelationRelationId ||
165  relid == DatabaseRelationId);
166 }

Referenced by CatalogCacheCreateEntry(), and IsInplaceUpdateRelation().

◆ IsInplaceUpdateRelation()

bool IsInplaceUpdateRelation ( Relation  relation)

Definition at line 152 of file catalog.c.

153 {
154  return IsInplaceUpdateOid(RelationGetRelid(relation));
155 }
bool IsInplaceUpdateOid(Oid relid)
Definition: catalog.c:162

References IsInplaceUpdateOid(), and RelationGetRelid.

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

◆ IsPinnedObject()

bool IsPinnedObject ( Oid  classId,
Oid  objectId 
)

Definition at line 341 of file catalog.c.

342 {
343  /*
344  * Objects with OIDs above FirstUnpinnedObjectId are never pinned. Since
345  * the OID generator skips this range when wrapping around, this check
346  * guarantees that user-defined objects are never considered pinned.
347  */
348  if (objectId >= FirstUnpinnedObjectId)
349  return false;
350 
351  /*
352  * Large objects are never pinned. We need this special case because
353  * their OIDs can be user-assigned.
354  */
355  if (classId == LargeObjectRelationId)
356  return false;
357 
358  /*
359  * There are a few objects defined in the catalog .dat files that, as a
360  * matter of policy, we prefer not to treat as pinned. We used to handle
361  * that by excluding them from pg_depend, but it's just as easy to
362  * hard-wire their OIDs here. (If the user does indeed drop and recreate
363  * them, they'll have new but certainly-unpinned OIDs, so no problem.)
364  *
365  * Checking both classId and objectId is overkill, since OIDs below
366  * FirstGenbkiObjectId should be globally unique, but do it anyway for
367  * robustness.
368  */
369 
370  /* the public namespace is not pinned */
371  if (classId == NamespaceRelationId &&
372  objectId == PG_PUBLIC_NAMESPACE)
373  return false;
374 
375  /*
376  * Databases are never pinned. It might seem that it'd be prudent to pin
377  * at least template0; but we do this intentionally so that template0 and
378  * template1 can be rebuilt from each other, thus letting them serve as
379  * mutual backups (as long as you've not modified template1, anyway).
380  */
381  if (classId == DatabaseRelationId)
382  return false;
383 
384  /*
385  * All other initdb-created objects are pinned. This is overkill (the
386  * system doesn't really depend on having every last weird datatype, for
387  * instance) but generating only the minimum required set of dependencies
388  * seems hard, and enforcing an accurate list would be much more expensive
389  * than the simple range test used here.
390  */
391  return true;
392 }

References FirstUnpinnedObjectId.

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

◆ IsReservedName()

bool IsReservedName ( const char *  name)

Definition at line 247 of file catalog.c.

248 {
249  /* ugly coding for speed */
250  return (name[0] == 'p' &&
251  name[1] == 'g' &&
252  name[2] == '_');
253 }
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 273 of file catalog.c.

274 {
275  /* These are the shared catalogs (look for BKI_SHARED_RELATION) */
276  if (relationId == AuthIdRelationId ||
277  relationId == AuthMemRelationId ||
278  relationId == DatabaseRelationId ||
279  relationId == DbRoleSettingRelationId ||
280  relationId == ParameterAclRelationId ||
281  relationId == ReplicationOriginRelationId ||
282  relationId == SharedDependRelationId ||
283  relationId == SharedDescriptionRelationId ||
284  relationId == SharedSecLabelRelationId ||
285  relationId == SubscriptionRelationId ||
286  relationId == TableSpaceRelationId)
287  return true;
288  /* These are their indexes */
289  if (relationId == AuthIdOidIndexId ||
290  relationId == AuthIdRolnameIndexId ||
291  relationId == AuthMemMemRoleIndexId ||
292  relationId == AuthMemRoleMemIndexId ||
293  relationId == AuthMemOidIndexId ||
294  relationId == AuthMemGrantorIndexId ||
295  relationId == DatabaseNameIndexId ||
296  relationId == DatabaseOidIndexId ||
297  relationId == DbRoleSettingDatidRolidIndexId ||
298  relationId == ParameterAclOidIndexId ||
299  relationId == ParameterAclParnameIndexId ||
300  relationId == ReplicationOriginIdentIndex ||
301  relationId == ReplicationOriginNameIndex ||
302  relationId == SharedDependDependerIndexId ||
303  relationId == SharedDependReferenceIndexId ||
304  relationId == SharedDescriptionObjIndexId ||
305  relationId == SharedSecLabelObjectIndexId ||
306  relationId == SubscriptionNameIndexId ||
307  relationId == SubscriptionObjectIndexId ||
308  relationId == TablespaceNameIndexId ||
309  relationId == TablespaceOidIndexId)
310  return true;
311  /* These are their toast tables and toast indexes */
312  if (relationId == PgDatabaseToastTable ||
313  relationId == PgDatabaseToastIndex ||
314  relationId == PgDbRoleSettingToastTable ||
315  relationId == PgDbRoleSettingToastIndex ||
316  relationId == PgParameterAclToastTable ||
317  relationId == PgParameterAclToastIndex ||
318  relationId == PgReplicationOriginToastTable ||
319  relationId == PgReplicationOriginToastIndex ||
320  relationId == PgShdescriptionToastTable ||
321  relationId == PgShdescriptionToastIndex ||
322  relationId == PgShseclabelToastTable ||
323  relationId == PgShseclabelToastIndex ||
324  relationId == PgSubscriptionToastTable ||
325  relationId == PgSubscriptionToastIndex ||
326  relationId == PgTablespaceToastTable ||
327  relationId == PgTablespaceToastIndex)
328  return true;
329  return false;
330 }

Referenced by CacheInvalidateCatalog(), CacheInvalidateHeapTuple(), 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 195 of file catalog.c.

196 {
197  Oid relnamespace = reltuple->relnamespace;
198 
199  return IsToastNamespace(relnamespace);
200 }
bool IsToastNamespace(Oid namespaceId)
Definition: catalog.c:230

References IsToastNamespace().

Referenced by IsSystemClass().

◆ IsToastNamespace()

bool IsToastNamespace ( Oid  namespaceId)

Definition at line 230 of file catalog.c.

231 {
232  return (namespaceId == PG_TOAST_NAMESPACE) ||
233  isTempToastNamespace(namespaceId);
234 }
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 175 of file catalog.c.

176 {
177  /*
178  * What we actually check is whether the relation belongs to a pg_toast
179  * namespace. This should be equivalent because of restrictions that are
180  * enforced elsewhere against creating user relations in, or moving
181  * relations into/out of, a pg_toast namespace. Notice also that this
182  * will not say "true" for toast tables belonging to other sessions' temp
183  * tables; we expect that other mechanisms will prevent access to those.
184  */
185  return IsToastNamespace(RelationGetNamespace(relation));
186 }
#define RelationGetNamespace(relation)
Definition: rel.h:546

References IsToastNamespace(), and RelationGetNamespace.

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

◆ pg_nextoid()

Datum pg_nextoid ( PG_FUNCTION_ARGS  )

Definition at line 614 of file catalog.c.

615 {
616  Oid reloid = PG_GETARG_OID(0);
618  Oid idxoid = PG_GETARG_OID(2);
619  Relation rel;
620  Relation idx;
621  HeapTuple atttuple;
622  Form_pg_attribute attform;
623  AttrNumber attno;
624  Oid newoid;
625 
626  /*
627  * As this function is not intended to be used during normal running, and
628  * only supports system catalogs (which require superuser permissions to
629  * modify), just checking for superuser ought to not obstruct valid
630  * usecases.
631  */
632  if (!superuser())
633  ereport(ERROR,
634  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
635  errmsg("must be superuser to call %s()",
636  "pg_nextoid")));
637 
638  rel = table_open(reloid, RowExclusiveLock);
639  idx = index_open(idxoid, RowExclusiveLock);
640 
641  if (!IsSystemRelation(rel))
642  ereport(ERROR,
643  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
644  errmsg("pg_nextoid() can only be used on system catalogs")));
645 
646  if (idx->rd_index->indrelid != RelationGetRelid(rel))
647  ereport(ERROR,
648  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
649  errmsg("index \"%s\" does not belong to table \"%s\"",
651  RelationGetRelationName(rel))));
652 
653  atttuple = SearchSysCacheAttName(reloid, NameStr(*attname));
654  if (!HeapTupleIsValid(atttuple))
655  ereport(ERROR,
656  (errcode(ERRCODE_UNDEFINED_COLUMN),
657  errmsg("column \"%s\" of relation \"%s\" does not exist",
659 
660  attform = ((Form_pg_attribute) GETSTRUCT(atttuple));
661  attno = attform->attnum;
662 
663  if (attform->atttypid != OIDOID)
664  ereport(ERROR,
665  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
666  errmsg("column \"%s\" is not of type oid",
667  NameStr(*attname))));
668 
670  idx->rd_index->indkey.values[0] != attno)
671  ereport(ERROR,
672  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
673  errmsg("index \"%s\" is not the index for column \"%s\"",
675  NameStr(*attname))));
676 
677  newoid = GetNewOidWithIndex(rel, idxoid, attno);
678 
679  ReleaseSysCache(atttuple);
682 
683  PG_RETURN_OID(newoid);
684 }
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:259
int16 AttrNumber
Definition: attnum.h:21
#define NameStr(name)
Definition: c.h:737
int errcode(int sqlerrcode)
Definition: elog.c:853
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_GETARG_NAME(n)
Definition: fmgr.h:278
#define PG_RETURN_OID(x)
Definition: fmgr.h:360
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
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
Definition: pg_attribute.h:41
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:209
#define IndexRelationGetNumberOfKeyAttributes(relation)
Definition: rel.h:524
Definition: c.h:732
bool superuser(void)
Definition: superuser.c:46
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269
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, 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 693 of file catalog.c.

694 {
695  /*
696  * Belt-and-suspenders check, since StopGeneratingPinnedObjectIds will
697  * fail anyway in non-single-user mode.
698  */
699  if (!superuser())
700  ereport(ERROR,
701  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
702  errmsg("must be superuser to call %s()",
703  "pg_stop_making_pinned_objects")));
704 
706 
707  PG_RETURN_VOID();
708 }
#define PG_RETURN_VOID()
Definition: fmgr.h:349
void StopGeneratingPinnedObjectIds(void)
Definition: varsup.c:652

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