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

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

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

204 {
205  return namespaceId == PG_CATALOG_NAMESPACE;
206 }

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_relation(), ReindexMultipleTables(), and ReindexRelationConcurrently().

◆ IsInplaceUpdateOid()

bool IsInplaceUpdateOid ( Oid  relid)

Definition at line 153 of file catalog.c.

154 {
155  return (relid == RelationRelationId ||
156  relid == DatabaseRelationId);
157 }

Referenced by CatalogCacheCreateEntry(), and IsInplaceUpdateRelation().

◆ IsInplaceUpdateRelation()

bool IsInplaceUpdateRelation ( Relation  relation)

Definition at line 143 of file catalog.c.

144 {
145  return IsInplaceUpdateOid(RelationGetRelid(relation));
146 }
bool IsInplaceUpdateOid(Oid relid)
Definition: catalog.c:153

References IsInplaceUpdateOid(), and RelationGetRelid.

◆ IsPinnedObject()

bool IsPinnedObject ( Oid  classId,
Oid  objectId 
)

Definition at line 334 of file catalog.c.

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

References FirstUnpinnedObjectId.

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

◆ IsReservedName()

bool IsReservedName ( const char *  name)

Definition at line 238 of file catalog.c.

239 {
240  /* ugly coding for speed */
241  return (name[0] == 'p' &&
242  name[1] == 'g' &&
243  name[2] == '_');
244 }
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 264 of file catalog.c.

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

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

187 {
188  Oid relnamespace = reltuple->relnamespace;
189 
190  return IsToastNamespace(relnamespace);
191 }
bool IsToastNamespace(Oid namespaceId)
Definition: catalog.c:221

References IsToastNamespace().

Referenced by IsSystemClass().

◆ IsToastNamespace()

bool IsToastNamespace ( Oid  namespaceId)

Definition at line 221 of file catalog.c.

222 {
223  return (namespaceId == PG_TOAST_NAMESPACE) ||
224  isTempToastNamespace(namespaceId);
225 }
bool isTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3646

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

167 {
168  /*
169  * What we actually check is whether the relation belongs to a pg_toast
170  * namespace. This should be equivalent because of restrictions that are
171  * enforced elsewhere against creating user relations in, or moving
172  * relations into/out of, a pg_toast namespace. Notice also that this
173  * will not say "true" for toast tables belonging to other sessions' temp
174  * tables; we expect that other mechanisms will prevent access to those.
175  */
176  return IsToastNamespace(RelationGetNamespace(relation));
177 }
#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 607 of file catalog.c.

608 {
609  Oid reloid = PG_GETARG_OID(0);
611  Oid idxoid = PG_GETARG_OID(2);
612  Relation rel;
613  Relation idx;
614  HeapTuple atttuple;
615  Form_pg_attribute attform;
616  AttrNumber attno;
617  Oid newoid;
618 
619  /*
620  * As this function is not intended to be used during normal running, and
621  * only supports system catalogs (which require superuser permissions to
622  * modify), just checking for superuser ought to not obstruct valid
623  * usecases.
624  */
625  if (!superuser())
626  ereport(ERROR,
627  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
628  errmsg("must be superuser to call %s()",
629  "pg_nextoid")));
630 
631  rel = table_open(reloid, RowExclusiveLock);
632  idx = index_open(idxoid, RowExclusiveLock);
633 
634  if (!IsSystemRelation(rel))
635  ereport(ERROR,
636  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
637  errmsg("pg_nextoid() can only be used on system catalogs")));
638 
639  if (idx->rd_index->indrelid != RelationGetRelid(rel))
640  ereport(ERROR,
641  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
642  errmsg("index \"%s\" does not belong to table \"%s\"",
644  RelationGetRelationName(rel))));
645 
646  atttuple = SearchSysCacheAttName(reloid, NameStr(*attname));
647  if (!HeapTupleIsValid(atttuple))
648  ereport(ERROR,
649  (errcode(ERRCODE_UNDEFINED_COLUMN),
650  errmsg("column \"%s\" of relation \"%s\" does not exist",
652 
653  attform = ((Form_pg_attribute) GETSTRUCT(atttuple));
654  attno = attform->attnum;
655 
656  if (attform->atttypid != OIDOID)
657  ereport(ERROR,
658  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
659  errmsg("column \"%s\" is not of type oid",
660  NameStr(*attname))));
661 
663  idx->rd_index->indkey.values[0] != attno)
664  ereport(ERROR,
665  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
666  errmsg("index \"%s\" is not the index for column \"%s\"",
668  NameStr(*attname))));
669 
670  newoid = GetNewOidWithIndex(rel, idxoid, attno);
671 
672  ReleaseSysCache(atttuple);
675 
676  PG_RETURN_OID(newoid);
677 }
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:259
int16 AttrNumber
Definition: attnum.h:21
#define NameStr(name)
Definition: c.h:746
int errcode(int sqlerrcode)
Definition: elog.c:855
#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:741
bool superuser(void)
Definition: superuser.c:46
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:266
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition: syscache.c:359
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 686 of file catalog.c.

687 {
688  /*
689  * Belt-and-suspenders check, since StopGeneratingPinnedObjectIds will
690  * fail anyway in non-single-user mode.
691  */
692  if (!superuser())
693  ereport(ERROR,
694  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
695  errmsg("must be superuser to call %s()",
696  "pg_stop_making_pinned_objects")));
697 
699 
700  PG_RETURN_VOID();
701 }
#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().