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/indexing.h"
#include "catalog/namespace.h"
#include "catalog/pg_auth_members.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_database.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_pltemplate.h"
#include "catalog/pg_db_role_setting.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 "catalog/toasting.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.

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)
 
Oid GetNewOidWithIndex (Relation relation, Oid indexId, AttrNumber oidcolumn)
 
Oid GetNewRelFileNode (Oid reltablespace, Relation pg_class, char relpersistence)
 
Datum pg_nextoid (PG_FUNCTION_ARGS)
 

Function Documentation

◆ GetNewOidWithIndex()

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

Definition at line 323 of file catalog.c.

References Assert, BTEqualStrategyNumber, CHECK_FOR_INTERRUPTS, GetNewObjectId(), HeapTupleIsValid, IsBinaryUpgrade, IsBootstrapProcessingMode, IsSystemRelation(), sort-test::key, ObjectIdGetDatum, RelationGetRelid, ScanKeyInit(), SnapshotAny, systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by AddEnumLabel(), AssignTypeArrayOid(), CollationCreate(), ConversionCreate(), create_proc_lang(), CreateAccessMethod(), CreateCast(), CreateConstraintEntry(), createdb(), CreateForeignDataWrapper(), CreateForeignServer(), CreateOpFamily(), CreatePolicy(), CreatePublication(), CreateRole(), CreateStatistics(), CreateSubscription(), CreateTableSpace(), CreateTransform(), CreateTrigger(), CreateUserMapping(), DefineOpClass(), DefineTSConfiguration(), DefineTSDictionary(), DefineTSParser(), DefineTSTemplate(), EnumValuesCreate(), GetNewRelFileNode(), insert_event_trigger_tuple(), InsertExtensionTuple(), InsertRule(), LargeObjectCreate(), NamespaceCreate(), OperatorCreate(), OperatorShellMake(), pg_nextoid(), ProcedureCreate(), publication_add_relation(), SetDefaultACL(), StoreAttrDefault(), storeOperators(), storeProcedures(), toast_save_datum(), TypeCreate(), and TypeShellMake().

324 {
325  Oid newOid;
326  SysScanDesc scan;
328  bool collides;
329 
330  /* Only system relations are supported */
331  Assert(IsSystemRelation(relation));
332 
333  /* In bootstrap mode, we don't have any indexes to use */
335  return GetNewObjectId();
336 
337  /*
338  * We should never be asked to generate a new pg_type OID during
339  * pg_upgrade; doing so would risk collisions with the OIDs it wants to
340  * assign. Hitting this assert means there's some path where we failed to
341  * ensure that a type OID is determined by commands in the dump script.
342  */
343  Assert(!IsBinaryUpgrade || RelationGetRelid(relation) != TypeRelationId);
344 
345  /* Generate new OIDs until we find one not in the table */
346  do
347  {
349 
350  newOid = GetNewObjectId();
351 
352  ScanKeyInit(&key,
353  oidcolumn,
354  BTEqualStrategyNumber, F_OIDEQ,
355  ObjectIdGetDatum(newOid));
356 
357  /* see notes above about using SnapshotAny */
358  scan = systable_beginscan(relation, indexId, true,
359  SnapshotAny, 1, &key);
360 
361  collides = HeapTupleIsValid(systable_getnext(scan));
362 
363  systable_endscan(scan);
364  } while (collides);
365 
366  return newOid;
367 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:525
bool IsSystemRelation(Relation relation)
Definition: catalog.c:70
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:352
bool IsBinaryUpgrade
Definition: globals.c:110
Oid GetNewObjectId(void)
Definition: varsup.c:509
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Assert(condition)
Definition: c.h:732
#define SnapshotAny
Definition: snapmgr.h:69
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:374
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
#define RelationGetRelid(relation)
Definition: rel.h:419
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ GetNewRelFileNode()

Oid GetNewRelFileNode ( Oid  reltablespace,
Relation  pg_class,
char  relpersistence 
)

Definition at line 386 of file catalog.c.

References Assert, RelFileNodeBackend::backend, BackendIdForTempRelations, CHECK_FOR_INTERRUPTS, ClassOidIndexId, RelFileNode::dbNode, elog, ERROR, GetNewObjectId(), GetNewOidWithIndex(), InvalidBackendId, InvalidOid, IsBinaryUpgrade, MAIN_FORKNUM, MyDatabaseId, MyDatabaseTableSpace, RelFileNodeBackend::node, pfree(), RelFileNode::relNode, relpath, and RelFileNode::spcNode.

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

387 {
388  RelFileNodeBackend rnode;
389  char *rpath;
390  bool collides;
391  BackendId backend;
392 
393  /*
394  * If we ever get here during pg_upgrade, there's something wrong; all
395  * relfilenode assignments during a binary-upgrade run should be
396  * determined by commands in the dump script.
397  */
399 
400  switch (relpersistence)
401  {
402  case RELPERSISTENCE_TEMP:
403  backend = BackendIdForTempRelations();
404  break;
405  case RELPERSISTENCE_UNLOGGED:
406  case RELPERSISTENCE_PERMANENT:
407  backend = InvalidBackendId;
408  break;
409  default:
410  elog(ERROR, "invalid relpersistence: %c", relpersistence);
411  return InvalidOid; /* placate compiler */
412  }
413 
414  /* This logic should match RelationInitPhysicalAddr */
415  rnode.node.spcNode = reltablespace ? reltablespace : MyDatabaseTableSpace;
416  rnode.node.dbNode = (rnode.node.spcNode == GLOBALTABLESPACE_OID) ? InvalidOid : MyDatabaseId;
417 
418  /*
419  * The relpath will vary based on the backend ID, so we must initialize
420  * that properly here to make sure that any collisions based on filename
421  * are properly detected.
422  */
423  rnode.backend = backend;
424 
425  do
426  {
428 
429  /* Generate the OID */
430  if (pg_class)
432  Anum_pg_class_oid);
433  else
434  rnode.node.relNode = GetNewObjectId();
435 
436  /* Check for existing file of same name */
437  rpath = relpath(rnode, MAIN_FORKNUM);
438 
439  if (access(rpath, F_OK) == 0)
440  {
441  /* definite collision */
442  collides = true;
443  }
444  else
445  {
446  /*
447  * Here we have a little bit of a dilemma: if errno is something
448  * other than ENOENT, should we declare a collision and loop? In
449  * practice it seems best to go ahead regardless of the errno. If
450  * there is a colliding file we will get an smgr failure when we
451  * attempt to create the new relation file.
452  */
453  collides = false;
454  }
455 
456  pfree(rpath);
457  } while (collides);
458 
459  return rnode.node.relNode;
460 }
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:323
bool IsBinaryUpgrade
Definition: globals.c:110
Oid MyDatabaseTableSpace
Definition: globals.c:87
Oid GetNewObjectId(void)
Definition: varsup.c:509
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ERROR
Definition: elog.h:43
char relpersistence
Definition: pg_class.h:78
#define BackendIdForTempRelations()
Definition: backendid.h:34
#define ClassOidIndexId
Definition: indexing.h:114
#define InvalidBackendId
Definition: backendid.h:23
int BackendId
Definition: backendid.h:21
Oid MyDatabaseId
Definition: globals.c:85
#define InvalidOid
Definition: postgres_ext.h:36
RelFileNode node
Definition: relfilenode.h:74
#define Assert(condition)
Definition: c.h:732
BackendId backend
Definition: relfilenode.h:75
#define elog(elevel,...)
Definition: elog.h:226
#define relpath(rnode, forknum)
Definition: relpath.h:87
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99

◆ IsCatalogNamespace()

bool IsCatalogNamespace ( Oid  namespaceId)

Definition at line 179 of file catalog.c.

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

180 {
181  return namespaceId == PG_CATALOG_NAMESPACE;
182 }

◆ IsCatalogRelation()

bool IsCatalogRelation ( Relation  relation)

◆ IsCatalogRelationOid()

bool IsCatalogRelationOid ( Oid  relid)

Definition at line 117 of file catalog.c.

References FirstBootstrapObjectId.

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

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

◆ IsReservedName()

bool IsReservedName ( const char *  name)

Definition at line 214 of file catalog.c.

Referenced by check_rolespec_name(), CreateRole(), CreateSchemaCommand(), CreateTableSpace(), pg_replication_origin_create(), RenameRole(), RenameSchema(), and RenameTableSpace().

215 {
216  /* ugly coding for speed */
217  return (name[0] == 'p' &&
218  name[1] == 'g' &&
219  name[2] == '_');
220 }
const char * name
Definition: encode.c:521

◆ IsSharedRelation()

bool IsSharedRelation ( Oid  relationId)

Definition at line 240 of file catalog.c.

References AuthIdOidIndexId, AuthIdRolnameIndexId, AuthMemMemRoleIndexId, AuthMemRoleMemIndexId, DatabaseNameIndexId, DatabaseOidIndexId, DbRoleSettingDatidRolidIndexId, PgAuthidToastIndex, PgAuthidToastTable, PgDatabaseToastIndex, PgDatabaseToastTable, PgDbRoleSettingToastIndex, PgDbRoleSettingToastTable, PgPlTemplateToastIndex, PgPlTemplateToastTable, PgReplicationOriginToastIndex, PgReplicationOriginToastTable, PgShdescriptionToastIndex, PgShdescriptionToastTable, PgShseclabelToastIndex, PgShseclabelToastTable, PgSubscriptionToastIndex, PgSubscriptionToastTable, PgTablespaceToastIndex, PgTablespaceToastTable, PLTemplateNameIndexId, ReplicationOriginIdentIndex, ReplicationOriginNameIndex, SharedDependDependerIndexId, SharedDependReferenceIndexId, SharedDescriptionObjIndexId, SharedSecLabelObjectIndexId, SubscriptionNameIndexId, SubscriptionObjectIndexId, TablespaceNameIndexId, and TablespaceOidIndexId.

Referenced by CacheInvalidateCatalog(), CacheInvalidateHeapTuple(), classIdGetDbId(), DeleteSecurityLabel(), get_object_address(), GetSecurityLabel(), RelationBuildLocalRelation(), SetLocktagRelationOid(), SetSecurityLabel(), and UpdateLogicalMappings().

241 {
242  /* These are the shared catalogs (look for BKI_SHARED_RELATION) */
243  if (relationId == AuthIdRelationId ||
244  relationId == AuthMemRelationId ||
245  relationId == DatabaseRelationId ||
246  relationId == PLTemplateRelationId ||
247  relationId == SharedDescriptionRelationId ||
248  relationId == SharedDependRelationId ||
249  relationId == SharedSecLabelRelationId ||
250  relationId == TableSpaceRelationId ||
251  relationId == DbRoleSettingRelationId ||
252  relationId == ReplicationOriginRelationId ||
253  relationId == SubscriptionRelationId)
254  return true;
255  /* These are their indexes (see indexing.h) */
256  if (relationId == AuthIdRolnameIndexId ||
257  relationId == AuthIdOidIndexId ||
258  relationId == AuthMemRoleMemIndexId ||
259  relationId == AuthMemMemRoleIndexId ||
260  relationId == DatabaseNameIndexId ||
261  relationId == DatabaseOidIndexId ||
262  relationId == PLTemplateNameIndexId ||
263  relationId == SharedDescriptionObjIndexId ||
264  relationId == SharedDependDependerIndexId ||
265  relationId == SharedDependReferenceIndexId ||
266  relationId == SharedSecLabelObjectIndexId ||
267  relationId == TablespaceOidIndexId ||
268  relationId == TablespaceNameIndexId ||
269  relationId == DbRoleSettingDatidRolidIndexId ||
270  relationId == ReplicationOriginIdentIndex ||
271  relationId == ReplicationOriginNameIndex ||
272  relationId == SubscriptionObjectIndexId ||
273  relationId == SubscriptionNameIndexId)
274  return true;
275  /* These are their toast tables and toast indexes (see toasting.h) */
276  if (relationId == PgAuthidToastTable ||
277  relationId == PgAuthidToastIndex ||
278  relationId == PgDatabaseToastTable ||
279  relationId == PgDatabaseToastIndex ||
280  relationId == PgDbRoleSettingToastTable ||
281  relationId == PgDbRoleSettingToastIndex ||
282  relationId == PgPlTemplateToastTable ||
283  relationId == PgPlTemplateToastIndex ||
284  relationId == PgReplicationOriginToastTable ||
285  relationId == PgReplicationOriginToastIndex ||
286  relationId == PgShdescriptionToastTable ||
287  relationId == PgShdescriptionToastIndex ||
288  relationId == PgShseclabelToastTable ||
289  relationId == PgShseclabelToastIndex ||
290  relationId == PgSubscriptionToastTable ||
291  relationId == PgSubscriptionToastIndex ||
292  relationId == PgTablespaceToastTable ||
293  relationId == PgTablespaceToastIndex)
294  return true;
295  return false;
296 }
#define PgShseclabelToastIndex
Definition: toasting.h:100
#define SharedDependDependerIndexId
Definition: indexing.h:226
#define PgAuthidToastTable
Definition: toasting.h:81
#define PgTablespaceToastTable
Definition: toasting.h:105
#define DbRoleSettingDatidRolidIndexId
Definition: indexing.h:317
#define PgShseclabelToastTable
Definition: toasting.h:99
#define AuthIdOidIndexId
Definition: indexing.h:101
#define PgSubscriptionToastTable
Definition: toasting.h:102
#define PgDatabaseToastTable
Definition: toasting.h:84
#define PgTablespaceToastIndex
Definition: toasting.h:106
#define ReplicationOriginIdentIndex
Definition: indexing.h:340
#define TablespaceOidIndexId
Definition: indexing.h:244
#define PgPlTemplateToastTable
Definition: toasting.h:90
#define PgShdescriptionToastTable
Definition: toasting.h:96
#define PgReplicationOriginToastTable
Definition: toasting.h:93
#define DatabaseOidIndexId
Definition: indexing.h:146
#define PgShdescriptionToastIndex
Definition: toasting.h:97
#define PgDbRoleSettingToastTable
Definition: toasting.h:87
#define AuthMemRoleMemIndexId
Definition: indexing.h:104
#define PLTemplateNameIndexId
Definition: indexing.h:210
#define PgPlTemplateToastIndex
Definition: toasting.h:91
#define SharedDescriptionObjIndexId
Definition: indexing.h:156
#define PgDatabaseToastIndex
Definition: toasting.h:85
#define PgAuthidToastIndex
Definition: toasting.h:82
#define PgReplicationOriginToastIndex
Definition: toasting.h:94
#define AuthMemMemRoleIndexId
Definition: indexing.h:106
#define DatabaseNameIndexId
Definition: indexing.h:144
#define SharedSecLabelObjectIndexId
Definition: indexing.h:323
#define TablespaceNameIndexId
Definition: indexing.h:246
#define SubscriptionNameIndexId
Definition: indexing.h:364
#define PgSubscriptionToastIndex
Definition: toasting.h:103
#define ReplicationOriginNameIndex
Definition: indexing.h:343
#define SharedDependReferenceIndexId
Definition: indexing.h:228
#define PgDbRoleSettingToastIndex
Definition: toasting.h:88
#define AuthIdRolnameIndexId
Definition: indexing.h:99
#define SubscriptionObjectIndexId
Definition: indexing.h:361

◆ IsSystemClass()

bool IsSystemClass ( Oid  relid,
Form_pg_class  reltuple 
)

Definition at line 82 of file catalog.c.

References IsCatalogRelationOid(), and IsToastClass().

Referenced by IsSystemRelation(), pg_class_aclmask(), RangeVarCallbackForAlterRelation(), RangeVarCallbackForDropRelation(), RangeVarCallbackForPolicy(), RangeVarCallbackForRenameRule(), RangeVarCallbackForRenameTrigger(), RangeVarCallbackOwnsRelation(), ReindexMultipleTables(), renameatt_check(), swap_relation_files(), and truncate_check_rel().

83 {
84  /* IsCatalogRelationOid is a bit faster, so test that first */
85  return (IsCatalogRelationOid(relid) || IsToastClass(reltuple));
86 }
bool IsCatalogRelationOid(Oid relid)
Definition: catalog.c:117
bool IsToastClass(Form_pg_class reltuple)
Definition: catalog.c:162

◆ IsSystemRelation()

◆ IsToastClass()

bool IsToastClass ( Form_pg_class  reltuple)

Definition at line 162 of file catalog.c.

References IsToastNamespace().

Referenced by IsSystemClass().

163 {
164  Oid relnamespace = reltuple->relnamespace;
165 
166  return IsToastNamespace(relnamespace);
167 }
bool IsToastNamespace(Oid namespaceId)
Definition: catalog.c:197
unsigned int Oid
Definition: postgres_ext.h:31

◆ IsToastNamespace()

bool IsToastNamespace ( Oid  namespaceId)

Definition at line 197 of file catalog.c.

References isTempToastNamespace().

Referenced by AlterTableMoveAll(), heap_create(), IsToastClass(), and IsToastRelation().

198 {
199  return (namespaceId == PG_TOAST_NAMESPACE) ||
200  isTempToastNamespace(namespaceId);
201 }
bool isTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3161

◆ IsToastRelation()

bool IsToastRelation ( Relation  relation)

Definition at line 142 of file catalog.c.

References IsToastNamespace(), and RelationGetNamespace.

Referenced by CacheInvalidateHeapTuple(), heap_abort_speculative(), ReorderBufferCommit(), and ReorderBufferToastAppendChunk().

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

◆ pg_nextoid()

Datum pg_nextoid ( PG_FUNCTION_ARGS  )

Definition at line 470 of file catalog.c.

References attname, ereport, errcode(), errmsg(), ERROR, GetNewOidWithIndex(), GETSTRUCT, HeapTupleIsValid, idx(), index_close(), index_open(), IndexRelationGetNumberOfKeyAttributes, IsSystemRelation(), NameStr, PG_GETARG_NAME, PG_GETARG_OID, RelationData::rd_index, RelationGetRelationName, RelationGetRelid, ReleaseSysCache(), RowExclusiveLock, SearchSysCacheAttName(), superuser(), table_close(), and table_open().

471 {
472  Oid reloid = PG_GETARG_OID(0);
474  Oid idxoid = PG_GETARG_OID(2);
475  Relation rel;
476  Relation idx;
477  HeapTuple atttuple;
478  Form_pg_attribute attform;
479  AttrNumber attno;
480  Oid newoid;
481 
482  /*
483  * As this function is not intended to be used during normal running, and
484  * only supports system catalogs (which require superuser permissions to
485  * modify), just checking for superuser ought to not obstruct valid
486  * usecases.
487  */
488  if (!superuser())
489  ereport(ERROR,
490  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
491  errmsg("must be superuser to call pg_nextoid()")));
492 
493  rel = table_open(reloid, RowExclusiveLock);
494  idx = index_open(idxoid, RowExclusiveLock);
495 
496  if (!IsSystemRelation(rel))
497  ereport(ERROR,
498  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
499  errmsg("pg_nextoid() can only be used on system catalogs")));
500 
501  if (idx->rd_index->indrelid != RelationGetRelid(rel))
502  ereport(ERROR,
503  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
504  errmsg("index \"%s\" does not belong to table \"%s\"",
506  RelationGetRelationName(rel))));
507 
508  atttuple = SearchSysCacheAttName(reloid, NameStr(*attname));
509  if (!HeapTupleIsValid(atttuple))
510  ereport(ERROR,
511  (errcode(ERRCODE_UNDEFINED_COLUMN),
512  errmsg("column \"%s\" of relation \"%s\" does not exist",
513  NameStr(*attname), RelationGetRelationName(rel))));
514 
515  attform = ((Form_pg_attribute) GETSTRUCT(atttuple));
516  attno = attform->attnum;
517 
518  if (attform->atttypid != OIDOID)
519  ereport(ERROR,
520  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
521  errmsg("column \"%s\" is not of type oid",
522  NameStr(*attname))));
523 
525  idx->rd_index->indkey.values[0] != attno)
526  ereport(ERROR,
527  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
528  errmsg("index \"%s\" is not the index for column \"%s\"",
530  NameStr(*attname))));
531 
532  newoid = GetNewOidWithIndex(rel, idxoid, attno);
533 
534  ReleaseSysCache(atttuple);
537 
538  return newoid;
539 }
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:323
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
bool IsSystemRelation(Relation relation)
Definition: catalog.c:70
int errcode(int sqlerrcode)
Definition: elog.c:570
bool superuser(void)
Definition: superuser.c:47
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:264
unsigned int Oid
Definition: postgres_ext.h:31
Form_pg_index rd_index
Definition: rel.h:143
#define ERROR
Definition: elog.h:43
NameData attname
Definition: pg_attribute.h:40
Definition: c.h:603
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
#define RowExclusiveLock
Definition: lockdefs.h:38
#define RelationGetRelationName(relation)
Definition: rel.h:453
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
#define IndexRelationGetNumberOfKeyAttributes(relation)
Definition: rel.h:438
#define ereport(elevel, rest)
Definition: elog.h:141
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition: syscache.c:1265
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:152
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define NameStr(name)
Definition: c.h:609
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
int16 AttrNumber
Definition: attnum.h:21
#define RelationGetRelid(relation)
Definition: rel.h:419
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:126
#define PG_GETARG_NAME(n)
Definition: fmgr.h:273