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/sysattr.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 "storage/fd.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 57 of file catalog.c.

◆ GETNEWOID_LOG_THRESHOLD

#define GETNEWOID_LOG_THRESHOLD   1000000

Definition at line 56 of file catalog.c.

Function Documentation

◆ GetNewOidWithIndex()

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

Definition at line 393 of file catalog.c.

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

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(), 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 502 of file catalog.c.

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

185 {
186  return namespaceId == PG_CATALOG_NAMESPACE;
187 }

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

◆ IsCatalogRelation()

◆ IsCatalogRelationOid()

bool IsCatalogRelationOid ( Oid  relid)

Definition at line 122 of file catalog.c.

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

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

References FirstUnpinnedObjectId.

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

◆ IsReservedName()

bool IsReservedName ( const char *  name)

Definition at line 219 of file catalog.c.

220 {
221  /* ugly coding for speed */
222  return (name[0] == 'p' &&
223  name[1] == 'g' &&
224  name[2] == '_');
225 }
const char * name
Definition: encode.c:561

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

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

Referenced by CacheInvalidateCatalog(), CacheInvalidateHeapTuple(), classIdGetDbId(), DeleteSecurityLabel(), get_object_address(), get_tables_to_cluster_partitioned(), GetSecurityLabel(), 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 167 of file catalog.c.

168 {
169  Oid relnamespace = reltuple->relnamespace;
170 
171  return IsToastNamespace(relnamespace);
172 }
bool IsToastNamespace(Oid namespaceId)
Definition: catalog.c:202

References IsToastNamespace().

Referenced by IsSystemClass().

◆ IsToastNamespace()

bool IsToastNamespace ( Oid  namespaceId)

Definition at line 202 of file catalog.c.

203 {
204  return (namespaceId == PG_TOAST_NAMESPACE) ||
205  isTempToastNamespace(namespaceId);
206 }
bool isTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3212

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

148 {
149  /*
150  * What we actually check is whether the relation belongs to a pg_toast
151  * namespace. This should be equivalent because of restrictions that are
152  * enforced elsewhere against creating user relations in, or moving
153  * relations into/out of, a pg_toast namespace. Notice also that this
154  * will not say "true" for toast tables belonging to other sessions' temp
155  * tables; we expect that other mechanisms will prevent access to those.
156  */
157  return IsToastNamespace(RelationGetNamespace(relation));
158 }
#define RelationGetNamespace(relation)
Definition: rel.h:542

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

589 {
590  Oid reloid = PG_GETARG_OID(0);
592  Oid idxoid = PG_GETARG_OID(2);
593  Relation rel;
594  Relation idx;
595  HeapTuple atttuple;
596  Form_pg_attribute attform;
597  AttrNumber attno;
598  Oid newoid;
599 
600  /*
601  * As this function is not intended to be used during normal running, and
602  * only supports system catalogs (which require superuser permissions to
603  * modify), just checking for superuser ought to not obstruct valid
604  * usecases.
605  */
606  if (!superuser())
607  ereport(ERROR,
608  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
609  errmsg("must be superuser to call %s()",
610  "pg_nextoid")));
611 
612  rel = table_open(reloid, RowExclusiveLock);
613  idx = index_open(idxoid, RowExclusiveLock);
614 
615  if (!IsSystemRelation(rel))
616  ereport(ERROR,
617  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
618  errmsg("pg_nextoid() can only be used on system catalogs")));
619 
620  if (idx->rd_index->indrelid != RelationGetRelid(rel))
621  ereport(ERROR,
622  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
623  errmsg("index \"%s\" does not belong to table \"%s\"",
625  RelationGetRelationName(rel))));
626 
627  atttuple = SearchSysCacheAttName(reloid, NameStr(*attname));
628  if (!HeapTupleIsValid(atttuple))
629  ereport(ERROR,
630  (errcode(ERRCODE_UNDEFINED_COLUMN),
631  errmsg("column \"%s\" of relation \"%s\" does not exist",
633 
634  attform = ((Form_pg_attribute) GETSTRUCT(atttuple));
635  attno = attform->attnum;
636 
637  if (attform->atttypid != OIDOID)
638  ereport(ERROR,
639  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
640  errmsg("column \"%s\" is not of type oid",
641  NameStr(*attname))));
642 
644  idx->rd_index->indkey.values[0] != attno)
645  ereport(ERROR,
646  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
647  errmsg("index \"%s\" is not the index for column \"%s\"",
649  NameStr(*attname))));
650 
651  newoid = GetNewOidWithIndex(rel, idxoid, attno);
652 
653  ReleaseSysCache(atttuple);
656 
657  PG_RETURN_OID(newoid);
658 }
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:259
int16 AttrNumber
Definition: attnum.h:21
#define NameStr(name)
Definition: c.h:682
int errcode(int sqlerrcode)
Definition: elog.c:735
#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:649
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:158
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:132
#define RowExclusiveLock
Definition: lockdefs.h:38
NameData attname
Definition: pg_attribute.h:41
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
#define IndexRelationGetNumberOfKeyAttributes(relation)
Definition: rel.h:520
Definition: c.h:677
bool superuser(void)
Definition: superuser.c:46
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1221
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition: syscache.c:1314
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 667 of file catalog.c.

668 {
669  /*
670  * Belt-and-suspenders check, since StopGeneratingPinnedObjectIds will
671  * fail anyway in non-single-user mode.
672  */
673  if (!superuser())
674  ereport(ERROR,
675  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
676  errmsg("must be superuser to call %s()",
677  "pg_stop_making_pinned_objects")));
678 
680 
681  PG_RETURN_VOID();
682 }
#define PG_RETURN_VOID()
Definition: fmgr.h:349
void StopGeneratingPinnedObjectIds(void)
Definition: varsup.c:625

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