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

392 {
393  Oid newOid;
394  SysScanDesc scan;
396  bool collides;
397  uint64 retries = 0;
398  uint64 retries_before_log = GETNEWOID_LOG_THRESHOLD;
399 
400  /* Only system relations are supported */
401  Assert(IsSystemRelation(relation));
402 
403  /* In bootstrap mode, we don't have any indexes to use */
405  return GetNewObjectId();
406 
407  /*
408  * We should never be asked to generate a new pg_type OID during
409  * pg_upgrade; doing so would risk collisions with the OIDs it wants to
410  * assign. Hitting this assert means there's some path where we failed to
411  * ensure that a type OID is determined by commands in the dump script.
412  */
413  Assert(!IsBinaryUpgrade || RelationGetRelid(relation) != TypeRelationId);
414 
415  /* Generate new OIDs until we find one not in the table */
416  do
417  {
419 
420  newOid = GetNewObjectId();
421 
422  ScanKeyInit(&key,
423  oidcolumn,
424  BTEqualStrategyNumber, F_OIDEQ,
425  ObjectIdGetDatum(newOid));
426 
427  /* see notes above about using SnapshotAny */
428  scan = systable_beginscan(relation, indexId, true,
429  SnapshotAny, 1, &key);
430 
431  collides = HeapTupleIsValid(systable_getnext(scan));
432 
433  systable_endscan(scan);
434 
435  /*
436  * Log that we iterate more than GETNEWOID_LOG_THRESHOLD but have not
437  * yet found OID unused in the relation. Then repeat logging with
438  * exponentially increasing intervals until we iterate more than
439  * GETNEWOID_LOG_MAX_INTERVAL. Finally repeat logging every
440  * GETNEWOID_LOG_MAX_INTERVAL unless an unused OID is found. This
441  * logic is necessary not to fill up the server log with the similar
442  * messages.
443  */
444  if (retries >= retries_before_log)
445  {
446  ereport(LOG,
447  (errmsg("still searching for an unused OID in relation \"%s\"",
448  RelationGetRelationName(relation)),
449  errdetail_plural("OID candidates have been checked %llu time, but no unused OID has been found yet.",
450  "OID candidates have been checked %llu times, but no unused OID has been found yet.",
451  retries,
452  (unsigned long long) retries)));
453 
454  /*
455  * Double the number of retries to do before logging next until it
456  * reaches GETNEWOID_LOG_MAX_INTERVAL.
457  */
458  if (retries_before_log * 2 <= GETNEWOID_LOG_MAX_INTERVAL)
459  retries_before_log *= 2;
460  else
461  retries_before_log += GETNEWOID_LOG_MAX_INTERVAL;
462  }
463 
464  retries++;
465  } while (collides);
466 
467  /*
468  * If at least one log message is emitted, also log the completion of OID
469  * assignment.
470  */
471  if (retries > GETNEWOID_LOG_THRESHOLD)
472  {
473  ereport(LOG,
474  (errmsg_plural("new OID has been assigned in relation \"%s\" after %llu retry",
475  "new OID has been assigned in relation \"%s\" after %llu retries",
476  retries,
477  RelationGetRelationName(relation), (unsigned long long) retries)));
478  }
479 
480  return newOid;
481 }
#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:1182
int errdetail_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:1297
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#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:118
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
Assert(fmt[strlen(fmt) - 1] !='\n')
#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 500 of file catalog.c.

501 {
502  RelFileLocatorBackend rlocator;
503  char *rpath;
504  bool collides;
505  ProcNumber procNumber;
506 
507  /*
508  * If we ever get here during pg_upgrade, there's something wrong; all
509  * relfilenumber assignments during a binary-upgrade run should be
510  * determined by commands in the dump script.
511  */
513 
514  switch (relpersistence)
515  {
516  case RELPERSISTENCE_TEMP:
517  procNumber = ProcNumberForTempRelations();
518  break;
519  case RELPERSISTENCE_UNLOGGED:
520  case RELPERSISTENCE_PERMANENT:
521  procNumber = INVALID_PROC_NUMBER;
522  break;
523  default:
524  elog(ERROR, "invalid relpersistence: %c", relpersistence);
525  return InvalidRelFileNumber; /* placate compiler */
526  }
527 
528  /* This logic should match RelationInitPhysicalAddr */
529  rlocator.locator.spcOid = reltablespace ? reltablespace : MyDatabaseTableSpace;
530  rlocator.locator.dbOid =
531  (rlocator.locator.spcOid == GLOBALTABLESPACE_OID) ?
533 
534  /*
535  * The relpath will vary based on the backend number, so we must
536  * initialize that properly here to make sure that any collisions based on
537  * filename are properly detected.
538  */
539  rlocator.backend = procNumber;
540 
541  do
542  {
544 
545  /* Generate the OID */
546  if (pg_class)
547  rlocator.locator.relNumber = GetNewOidWithIndex(pg_class, ClassOidIndexId,
548  Anum_pg_class_oid);
549  else
550  rlocator.locator.relNumber = GetNewObjectId();
551 
552  /* Check for existing file of same name */
553  rpath = relpath(rlocator, MAIN_FORKNUM);
554 
555  if (access(rpath, F_OK) == 0)
556  {
557  /* definite collision */
558  collides = true;
559  }
560  else
561  {
562  /*
563  * Here we have a little bit of a dilemma: if errno is something
564  * other than ENOENT, should we declare a collision and loop? In
565  * practice it seems best to go ahead regardless of the errno. If
566  * there is a colliding file we will get an smgr failure when we
567  * attempt to create the new relation file.
568  */
569  collides = false;
570  }
571 
572  pfree(rpath);
573  } while (collides);
574 
575  return rlocator.locator.relNumber;
576 }
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:391
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
Oid MyDatabaseTableSpace
Definition: globals.c:93
Oid MyDatabaseId
Definition: globals.c:91
void pfree(void *pointer)
Definition: mcxt.c:1508
#define InvalidOid
Definition: postgres_ext.h:36
short access
Definition: preproc-type.c:36
#define ProcNumberForTempRelations()
Definition: proc.h:320
#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 182 of file catalog.c.

183 {
184  return namespaceId == PG_CATALOG_NAMESPACE;
185 }

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

◆ IsPinnedObject()

bool IsPinnedObject ( Oid  classId,
Oid  objectId 
)

Definition at line 313 of file catalog.c.

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

References FirstUnpinnedObjectId.

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

◆ IsReservedName()

bool IsReservedName ( const char *  name)

Definition at line 217 of file catalog.c.

218 {
219  /* ugly coding for speed */
220  return (name[0] == 'p' &&
221  name[1] == 'g' &&
222  name[2] == '_');
223 }
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 243 of file catalog.c.

244 {
245  /* These are the shared catalogs (look for BKI_SHARED_RELATION) */
246  if (relationId == AuthIdRelationId ||
247  relationId == AuthMemRelationId ||
248  relationId == DatabaseRelationId ||
249  relationId == DbRoleSettingRelationId ||
250  relationId == ParameterAclRelationId ||
251  relationId == ReplicationOriginRelationId ||
252  relationId == SharedDependRelationId ||
253  relationId == SharedDescriptionRelationId ||
254  relationId == SharedSecLabelRelationId ||
255  relationId == SubscriptionRelationId ||
256  relationId == TableSpaceRelationId)
257  return true;
258  /* These are their indexes */
259  if (relationId == AuthIdOidIndexId ||
260  relationId == AuthIdRolnameIndexId ||
261  relationId == AuthMemMemRoleIndexId ||
262  relationId == AuthMemRoleMemIndexId ||
263  relationId == AuthMemOidIndexId ||
264  relationId == AuthMemGrantorIndexId ||
265  relationId == DatabaseNameIndexId ||
266  relationId == DatabaseOidIndexId ||
267  relationId == DbRoleSettingDatidRolidIndexId ||
268  relationId == ParameterAclOidIndexId ||
269  relationId == ParameterAclParnameIndexId ||
270  relationId == ReplicationOriginIdentIndex ||
271  relationId == ReplicationOriginNameIndex ||
272  relationId == SharedDependDependerIndexId ||
273  relationId == SharedDependReferenceIndexId ||
274  relationId == SharedDescriptionObjIndexId ||
275  relationId == SharedSecLabelObjectIndexId ||
276  relationId == SubscriptionNameIndexId ||
277  relationId == SubscriptionObjectIndexId ||
278  relationId == TablespaceNameIndexId ||
279  relationId == TablespaceOidIndexId)
280  return true;
281  /* These are their toast tables and toast indexes */
282  if (relationId == PgAuthidToastTable ||
283  relationId == PgAuthidToastIndex ||
284  relationId == PgDatabaseToastTable ||
285  relationId == PgDatabaseToastIndex ||
286  relationId == PgDbRoleSettingToastTable ||
287  relationId == PgDbRoleSettingToastIndex ||
288  relationId == PgParameterAclToastTable ||
289  relationId == PgParameterAclToastIndex ||
290  relationId == PgReplicationOriginToastTable ||
291  relationId == PgReplicationOriginToastIndex ||
292  relationId == PgShdescriptionToastTable ||
293  relationId == PgShdescriptionToastIndex ||
294  relationId == PgShseclabelToastTable ||
295  relationId == PgShseclabelToastIndex ||
296  relationId == PgSubscriptionToastTable ||
297  relationId == PgSubscriptionToastIndex ||
298  relationId == PgTablespaceToastTable ||
299  relationId == PgTablespaceToastIndex)
300  return true;
301  return false;
302 }

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

166 {
167  Oid relnamespace = reltuple->relnamespace;
168 
169  return IsToastNamespace(relnamespace);
170 }
bool IsToastNamespace(Oid namespaceId)
Definition: catalog.c:200

References IsToastNamespace().

Referenced by IsSystemClass().

◆ IsToastNamespace()

bool IsToastNamespace ( Oid  namespaceId)

Definition at line 200 of file catalog.c.

201 {
202  return (namespaceId == PG_TOAST_NAMESPACE) ||
203  isTempToastNamespace(namespaceId);
204 }
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 145 of file catalog.c.

146 {
147  /*
148  * What we actually check is whether the relation belongs to a pg_toast
149  * namespace. This should be equivalent because of restrictions that are
150  * enforced elsewhere against creating user relations in, or moving
151  * relations into/out of, a pg_toast namespace. Notice also that this
152  * will not say "true" for toast tables belonging to other sessions' temp
153  * tables; we expect that other mechanisms will prevent access to those.
154  */
155  return IsToastNamespace(RelationGetNamespace(relation));
156 }
#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 586 of file catalog.c.

587 {
588  Oid reloid = PG_GETARG_OID(0);
590  Oid idxoid = PG_GETARG_OID(2);
591  Relation rel;
592  Relation idx;
593  HeapTuple atttuple;
594  Form_pg_attribute attform;
595  AttrNumber attno;
596  Oid newoid;
597 
598  /*
599  * As this function is not intended to be used during normal running, and
600  * only supports system catalogs (which require superuser permissions to
601  * modify), just checking for superuser ought to not obstruct valid
602  * usecases.
603  */
604  if (!superuser())
605  ereport(ERROR,
606  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
607  errmsg("must be superuser to call %s()",
608  "pg_nextoid")));
609 
610  rel = table_open(reloid, RowExclusiveLock);
611  idx = index_open(idxoid, RowExclusiveLock);
612 
613  if (!IsSystemRelation(rel))
614  ereport(ERROR,
615  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
616  errmsg("pg_nextoid() can only be used on system catalogs")));
617 
618  if (idx->rd_index->indrelid != RelationGetRelid(rel))
619  ereport(ERROR,
620  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
621  errmsg("index \"%s\" does not belong to table \"%s\"",
623  RelationGetRelationName(rel))));
624 
625  atttuple = SearchSysCacheAttName(reloid, NameStr(*attname));
626  if (!HeapTupleIsValid(atttuple))
627  ereport(ERROR,
628  (errcode(ERRCODE_UNDEFINED_COLUMN),
629  errmsg("column \"%s\" of relation \"%s\" does not exist",
631 
632  attform = ((Form_pg_attribute) GETSTRUCT(atttuple));
633  attno = attform->attnum;
634 
635  if (attform->atttypid != OIDOID)
636  ereport(ERROR,
637  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
638  errmsg("column \"%s\" is not of type oid",
639  NameStr(*attname))));
640 
642  idx->rd_index->indkey.values[0] != attno)
643  ereport(ERROR,
644  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
645  errmsg("index \"%s\" is not the index for column \"%s\"",
647  NameStr(*attname))));
648 
649  newoid = GetNewOidWithIndex(rel, idxoid, attno);
650 
651  ReleaseSysCache(atttuple);
654 
655  PG_RETURN_OID(newoid);
656 }
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:259
int16 AttrNumber
Definition: attnum.h:21
#define NameStr(name)
Definition: c.h:733
int errcode(int sqlerrcode)
Definition: elog.c:859
#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:728
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 665 of file catalog.c.

666 {
667  /*
668  * Belt-and-suspenders check, since StopGeneratingPinnedObjectIds will
669  * fail anyway in non-single-user mode.
670  */
671  if (!superuser())
672  ereport(ERROR,
673  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
674  errmsg("must be superuser to call %s()",
675  "pg_stop_making_pinned_objects")));
676 
678 
679  PG_RETURN_VOID();
680 }
#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().