PostgreSQL Source Code  git master
alter.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/relation.h"
#include "access/table.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_conversion.h"
#include "catalog/pg_database_d.h"
#include "catalog/pg_event_trigger.h"
#include "catalog/pg_foreign_data_wrapper.h"
#include "catalog/pg_foreign_server.h"
#include "catalog/pg_language.h"
#include "catalog/pg_largeobject.h"
#include "catalog/pg_largeobject_metadata.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_opfamily.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_statistic_ext.h"
#include "catalog/pg_subscription.h"
#include "catalog/pg_ts_config.h"
#include "catalog/pg_ts_dict.h"
#include "catalog/pg_ts_parser.h"
#include "catalog/pg_ts_template.h"
#include "commands/alter.h"
#include "commands/collationcmds.h"
#include "commands/dbcommands.h"
#include "commands/defrem.h"
#include "commands/event_trigger.h"
#include "commands/extension.h"
#include "commands/policy.h"
#include "commands/publicationcmds.h"
#include "commands/schemacmds.h"
#include "commands/subscriptioncmds.h"
#include "commands/tablecmds.h"
#include "commands/tablespace.h"
#include "commands/trigger.h"
#include "commands/typecmds.h"
#include "commands/user.h"
#include "miscadmin.h"
#include "replication/logicalworker.h"
#include "rewrite/rewriteDefine.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/syscache.h"
Include dependency graph for alter.c:

Go to the source code of this file.

Functions

static Oid AlterObjectNamespace_internal (Relation rel, Oid objid, Oid nspOid)
 
static void report_name_conflict (Oid classId, const char *name)
 
static void report_namespace_conflict (Oid classId, const char *name, Oid nspOid)
 
static void AlterObjectRename_internal (Relation rel, Oid objectId, const char *new_name)
 
ObjectAddress ExecRenameStmt (RenameStmt *stmt)
 
ObjectAddress ExecAlterObjectDependsStmt (AlterObjectDependsStmt *stmt, ObjectAddress *refAddress)
 
ObjectAddress ExecAlterObjectSchemaStmt (AlterObjectSchemaStmt *stmt, ObjectAddress *oldSchemaAddr)
 
Oid AlterObjectNamespace_oid (Oid classId, Oid objid, Oid nspOid, ObjectAddresses *objsMoved)
 
ObjectAddress ExecAlterOwnerStmt (AlterOwnerStmt *stmt)
 
void AlterObjectOwner_internal (Oid classId, Oid objectId, Oid new_ownerId)
 

Function Documentation

◆ AlterObjectNamespace_internal()

static Oid AlterObjectNamespace_internal ( Relation  rel,
Oid  objid,
Oid  nspOid 
)
static

Definition at line 680 of file alter.c.

681 {
682  Oid classId = RelationGetRelid(rel);
683  int oidCacheId = get_object_catcache_oid(classId);
684  int nameCacheId = get_object_catcache_name(classId);
685  AttrNumber Anum_name = get_object_attnum_name(classId);
686  AttrNumber Anum_namespace = get_object_attnum_namespace(classId);
687  AttrNumber Anum_owner = get_object_attnum_owner(classId);
688  Oid oldNspOid;
689  Datum name,
690  namespace;
691  bool isnull;
692  HeapTuple tup,
693  newtup;
694  Datum *values;
695  bool *nulls;
696  bool *replaces;
697 
698  tup = SearchSysCacheCopy1(oidCacheId, ObjectIdGetDatum(objid));
699  if (!HeapTupleIsValid(tup)) /* should not happen */
700  elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
701  objid, RelationGetRelationName(rel));
702 
703  name = heap_getattr(tup, Anum_name, RelationGetDescr(rel), &isnull);
704  Assert(!isnull);
705  namespace = heap_getattr(tup, Anum_namespace, RelationGetDescr(rel),
706  &isnull);
707  Assert(!isnull);
708  oldNspOid = DatumGetObjectId(namespace);
709 
710  /*
711  * If the object is already in the correct namespace, we don't need to do
712  * anything except fire the object access hook.
713  */
714  if (oldNspOid == nspOid)
715  {
716  InvokeObjectPostAlterHook(classId, objid, 0);
717  return oldNspOid;
718  }
719 
720  /* Check basic namespace related issues */
721  CheckSetNamespace(oldNspOid, nspOid);
722 
723  /* Permission checks ... superusers can always do it */
724  if (!superuser())
725  {
726  Datum owner;
727  Oid ownerId;
728  AclResult aclresult;
729 
730  /* Fail if object does not have an explicit owner */
731  if (Anum_owner <= 0)
732  ereport(ERROR,
733  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
734  errmsg("must be superuser to set schema of %s",
735  getObjectDescriptionOids(classId, objid))));
736 
737  /* Otherwise, must be owner of the existing object */
738  owner = heap_getattr(tup, Anum_owner, RelationGetDescr(rel), &isnull);
739  Assert(!isnull);
740  ownerId = DatumGetObjectId(owner);
741 
742  if (!has_privs_of_role(GetUserId(), ownerId))
744  NameStr(*(DatumGetName(name))));
745 
746  /* User must have CREATE privilege on new namespace */
747  aclresult = object_aclcheck(NamespaceRelationId, nspOid, GetUserId(), ACL_CREATE);
748  if (aclresult != ACLCHECK_OK)
749  aclcheck_error(aclresult, OBJECT_SCHEMA,
750  get_namespace_name(nspOid));
751  }
752 
753  /*
754  * Check for duplicate name (more friendly than unique-index failure).
755  * Since this is just a friendliness check, we can just skip it in cases
756  * where there isn't suitable support.
757  */
758  if (classId == ProcedureRelationId)
759  {
760  Form_pg_proc proc = (Form_pg_proc) GETSTRUCT(tup);
761 
762  IsThereFunctionInNamespace(NameStr(proc->proname), proc->pronargs,
763  &proc->proargtypes, nspOid);
764  }
765  else if (classId == CollationRelationId)
766  {
768 
769  IsThereCollationInNamespace(NameStr(coll->collname), nspOid);
770  }
771  else if (classId == OperatorClassRelationId)
772  {
774 
775  IsThereOpClassInNamespace(NameStr(opc->opcname),
776  opc->opcmethod, nspOid);
777  }
778  else if (classId == OperatorFamilyRelationId)
779  {
781 
782  IsThereOpFamilyInNamespace(NameStr(opf->opfname),
783  opf->opfmethod, nspOid);
784  }
785  else if (nameCacheId >= 0 &&
786  SearchSysCacheExists2(nameCacheId, name,
787  ObjectIdGetDatum(nspOid)))
790  nspOid);
791 
792  /* Build modified tuple */
794  nulls = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
795  replaces = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
796  values[Anum_namespace - 1] = ObjectIdGetDatum(nspOid);
797  replaces[Anum_namespace - 1] = true;
798  newtup = heap_modify_tuple(tup, RelationGetDescr(rel),
799  values, nulls, replaces);
800 
801  /* Perform actual update */
802  CatalogTupleUpdate(rel, &tup->t_self, newtup);
803 
804  /* Release memory */
805  pfree(values);
806  pfree(nulls);
807  pfree(replaces);
808 
809  /* update dependency to point to the new schema */
810  if (changeDependencyFor(classId, objid,
811  NamespaceRelationId, oldNspOid, nspOid) != 1)
812  elog(ERROR, "could not change schema dependency for object %u",
813  objid);
814 
815  InvokeObjectPostAlterHook(classId, objid, 0);
816 
817  return oldNspOid;
818 }
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:5128
AclResult
Definition: acl.h:182
@ ACLCHECK_OK
Definition: acl.h:183
@ ACLCHECK_NOT_OWNER
Definition: acl.h:185
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2688
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition: aclchk.c:3876
static void report_namespace_conflict(Oid classId, const char *name, Oid nspOid)
Definition: alter.c:110
int16 AttrNumber
Definition: attnum.h:21
static Datum values[MAXATTR]
Definition: bootstrap.c:152
#define NameStr(name)
Definition: c.h:746
#define Assert(condition)
Definition: c.h:858
void IsThereCollationInNamespace(const char *collname, Oid nspOid)
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
#define ereport(elevel,...)
Definition: elog.h:149
void IsThereFunctionInNamespace(const char *proname, int pronargs, oidvector *proargtypes, Oid nspOid)
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition: heaptuple.c:1209
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:792
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:313
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3366
void pfree(void *pointer)
Definition: mcxt.c:1520
void * palloc0(Size size)
Definition: mcxt.c:1346
Oid GetUserId(void)
Definition: miscinit.c:514
void CheckSetNamespace(Oid oldNspOid, Oid nspOid)
Definition: namespace.c:3444
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:197
int get_object_catcache_name(Oid class_id)
AttrNumber get_object_attnum_owner(Oid class_id)
char * getObjectDescriptionOids(Oid classid, Oid objid)
AttrNumber get_object_attnum_namespace(Oid class_id)
AttrNumber get_object_attnum_name(Oid class_id)
int get_object_catcache_oid(Oid class_id)
ObjectType get_object_type(Oid class_id, Oid object_id)
void IsThereOpFamilyInNamespace(const char *opfname, Oid opfmethod, Oid opfnamespace)
Definition: opclasscmds.c:1730
void IsThereOpClassInNamespace(const char *opcname, Oid opcmethod, Oid opcnamespace)
Definition: opclasscmds.c:1707
@ OBJECT_SCHEMA
Definition: parsenodes.h:2299
#define ACL_CREATE
Definition: parsenodes.h:85
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:58
long changeDependencyFor(Oid classId, Oid objectId, Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId)
Definition: pg_depend.c:456
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:83
FormData_pg_opfamily * Form_pg_opfamily
Definition: pg_opfamily.h:51
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:136
static Name DatumGetName(Datum X)
Definition: postgres.h:360
uintptr_t Datum
Definition: postgres.h:64
static Oid DatumGetObjectId(Datum X)
Definition: postgres.h:242
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 RelationGetDescr(relation)
Definition: rel.h:531
#define RelationGetNumberOfAttributes(relation)
Definition: rel.h:511
#define RelationGetRelationName(relation)
Definition: rel.h:539
ItemPointerData t_self
Definition: htup.h:65
bool superuser(void)
Definition: superuser.c:46
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:86
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:97
const char * name

References ACL_CREATE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, Assert, CatalogTupleUpdate(), changeDependencyFor(), CheckSetNamespace(), DatumGetName(), DatumGetObjectId(), elog, ereport, errcode(), errmsg(), ERROR, get_namespace_name(), get_object_attnum_name(), get_object_attnum_namespace(), get_object_attnum_owner(), get_object_catcache_name(), get_object_catcache_oid(), get_object_type(), getObjectDescriptionOids(), GETSTRUCT, GetUserId(), has_privs_of_role(), heap_getattr(), heap_modify_tuple(), HeapTupleIsValid, InvokeObjectPostAlterHook, IsThereCollationInNamespace(), IsThereFunctionInNamespace(), IsThereOpClassInNamespace(), IsThereOpFamilyInNamespace(), name, NameStr, object_aclcheck(), OBJECT_SCHEMA, ObjectIdGetDatum(), palloc0(), pfree(), RelationGetDescr, RelationGetNumberOfAttributes, RelationGetRelationName, RelationGetRelid, report_namespace_conflict(), SearchSysCacheCopy1, SearchSysCacheExists2, superuser(), HeapTupleData::t_self, and values.

Referenced by AlterObjectNamespace_oid(), and ExecAlterObjectSchemaStmt().

◆ AlterObjectNamespace_oid()

Oid AlterObjectNamespace_oid ( Oid  classId,
Oid  objid,
Oid  nspOid,
ObjectAddresses objsMoved 
)

Definition at line 613 of file alter.c.

615 {
616  Oid oldNspOid = InvalidOid;
617 
618  switch (classId)
619  {
620  case RelationRelationId:
621  {
622  Relation rel;
623 
624  rel = relation_open(objid, AccessExclusiveLock);
625  oldNspOid = RelationGetNamespace(rel);
626 
627  AlterTableNamespaceInternal(rel, oldNspOid, nspOid, objsMoved);
628 
629  relation_close(rel, NoLock);
630  break;
631  }
632 
633  case TypeRelationId:
634  oldNspOid = AlterTypeNamespace_oid(objid, nspOid, objsMoved);
635  break;
636 
637  case ProcedureRelationId:
638  case CollationRelationId:
639  case ConversionRelationId:
640  case OperatorRelationId:
641  case OperatorClassRelationId:
642  case OperatorFamilyRelationId:
643  case StatisticExtRelationId:
644  case TSParserRelationId:
645  case TSDictionaryRelationId:
646  case TSTemplateRelationId:
647  case TSConfigRelationId:
648  {
649  Relation catalog;
650 
651  catalog = table_open(classId, RowExclusiveLock);
652 
653  oldNspOid = AlterObjectNamespace_internal(catalog, objid,
654  nspOid);
655 
656  table_close(catalog, RowExclusiveLock);
657  }
658  break;
659 
660  default:
661  /* ignore object types that don't have schema-qualified names */
663  }
664 
665  return oldNspOid;
666 }
static Oid AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
Definition: alter.c:680
#define InvalidAttrNumber
Definition: attnum.h:23
#define NoLock
Definition: lockdefs.h:34
#define AccessExclusiveLock
Definition: lockdefs.h:43
#define RowExclusiveLock
Definition: lockdefs.h:38
#define InvalidOid
Definition: postgres_ext.h:36
#define RelationGetNamespace(relation)
Definition: rel.h:546
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: relation.c:205
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: relation.c:47
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40
void AlterTableNamespaceInternal(Relation rel, Oid oldNspOid, Oid nspOid, ObjectAddresses *objsMoved)
Definition: tablecmds.c:17947
Oid AlterTypeNamespace_oid(Oid typeOid, Oid nspOid, ObjectAddresses *objsMoved)
Definition: typecmds.c:4094

References AccessExclusiveLock, AlterObjectNamespace_internal(), AlterTableNamespaceInternal(), AlterTypeNamespace_oid(), Assert, get_object_attnum_namespace(), InvalidAttrNumber, InvalidOid, NoLock, relation_close(), relation_open(), RelationGetNamespace, RowExclusiveLock, table_close(), and table_open().

Referenced by AlterExtensionNamespace().

◆ AlterObjectOwner_internal()

void AlterObjectOwner_internal ( Oid  classId,
Oid  objectId,
Oid  new_ownerId 
)

Definition at line 916 of file alter.c.

917 {
918  /* For large objects, the catalog to modify is pg_largeobject_metadata */
919  Oid catalogId = (classId == LargeObjectRelationId) ? LargeObjectMetadataRelationId : classId;
920  AttrNumber Anum_oid = get_object_attnum_oid(catalogId);
921  AttrNumber Anum_owner = get_object_attnum_owner(catalogId);
922  AttrNumber Anum_namespace = get_object_attnum_namespace(catalogId);
923  AttrNumber Anum_acl = get_object_attnum_acl(catalogId);
924  AttrNumber Anum_name = get_object_attnum_name(catalogId);
925  Relation rel;
926  HeapTuple oldtup;
927  Datum datum;
928  bool isnull;
929  Oid old_ownerId;
930  Oid namespaceId = InvalidOid;
931 
932  rel = table_open(catalogId, RowExclusiveLock);
933 
934  oldtup = get_catalog_object_by_oid(rel, Anum_oid, objectId);
935  if (oldtup == NULL)
936  elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
937  objectId, RelationGetRelationName(rel));
938 
939  datum = heap_getattr(oldtup, Anum_owner,
940  RelationGetDescr(rel), &isnull);
941  Assert(!isnull);
942  old_ownerId = DatumGetObjectId(datum);
943 
944  if (Anum_namespace != InvalidAttrNumber)
945  {
946  datum = heap_getattr(oldtup, Anum_namespace,
947  RelationGetDescr(rel), &isnull);
948  Assert(!isnull);
949  namespaceId = DatumGetObjectId(datum);
950  }
951 
952  if (old_ownerId != new_ownerId)
953  {
954  AttrNumber nattrs;
955  HeapTuple newtup;
956  Datum *values;
957  bool *nulls;
958  bool *replaces;
959 
960  /* Superusers can bypass permission checks */
961  if (!superuser())
962  {
963  /* must be owner */
964  if (!has_privs_of_role(GetUserId(), old_ownerId))
965  {
966  char *objname;
967  char namebuf[NAMEDATALEN];
968 
969  if (Anum_name != InvalidAttrNumber)
970  {
971  datum = heap_getattr(oldtup, Anum_name,
972  RelationGetDescr(rel), &isnull);
973  Assert(!isnull);
974  objname = NameStr(*DatumGetName(datum));
975  }
976  else
977  {
978  snprintf(namebuf, sizeof(namebuf), "%u", objectId);
979  objname = namebuf;
980  }
982  get_object_type(catalogId, objectId),
983  objname);
984  }
985  /* Must be able to become new owner */
986  check_can_set_role(GetUserId(), new_ownerId);
987 
988  /* New owner must have CREATE privilege on namespace */
989  if (OidIsValid(namespaceId))
990  {
991  AclResult aclresult;
992 
993  aclresult = object_aclcheck(NamespaceRelationId, namespaceId, new_ownerId,
994  ACL_CREATE);
995  if (aclresult != ACLCHECK_OK)
996  aclcheck_error(aclresult, OBJECT_SCHEMA,
997  get_namespace_name(namespaceId));
998  }
999  }
1000 
1001  /* Build a modified tuple */
1002  nattrs = RelationGetNumberOfAttributes(rel);
1003  values = palloc0(nattrs * sizeof(Datum));
1004  nulls = palloc0(nattrs * sizeof(bool));
1005  replaces = palloc0(nattrs * sizeof(bool));
1006  values[Anum_owner - 1] = ObjectIdGetDatum(new_ownerId);
1007  replaces[Anum_owner - 1] = true;
1008 
1009  /*
1010  * Determine the modified ACL for the new owner. This is only
1011  * necessary when the ACL is non-null.
1012  */
1013  if (Anum_acl != InvalidAttrNumber)
1014  {
1015  datum = heap_getattr(oldtup,
1016  Anum_acl, RelationGetDescr(rel), &isnull);
1017  if (!isnull)
1018  {
1019  Acl *newAcl;
1020 
1021  newAcl = aclnewowner(DatumGetAclP(datum),
1022  old_ownerId, new_ownerId);
1023  values[Anum_acl - 1] = PointerGetDatum(newAcl);
1024  replaces[Anum_acl - 1] = true;
1025  }
1026  }
1027 
1028  newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel),
1029  values, nulls, replaces);
1030 
1031  /* Perform actual update */
1032  CatalogTupleUpdate(rel, &newtup->t_self, newtup);
1033 
1034  /* Update owner dependency reference */
1035  changeDependencyOnOwner(classId, objectId, new_ownerId);
1036 
1037  /* Release memory */
1038  pfree(values);
1039  pfree(nulls);
1040  pfree(replaces);
1041  }
1042 
1043  /* Note the post-alter hook gets classId not catalogId */
1044  InvokeObjectPostAlterHook(classId, objectId, 0);
1045 
1047 }
Acl * aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
Definition: acl.c:1096
void check_can_set_role(Oid member, Oid role)
Definition: acl.c:5185
#define DatumGetAclP(X)
Definition: acl.h:120
#define OidIsValid(objectId)
Definition: c.h:775
HeapTuple get_catalog_object_by_oid(Relation catalog, AttrNumber oidcol, Oid objectId)
AttrNumber get_object_attnum_oid(Oid class_id)
AttrNumber get_object_attnum_acl(Oid class_id)
#define NAMEDATALEN
void changeDependencyOnOwner(Oid classId, Oid objectId, Oid newOwnerId)
Definition: pg_shdepend.c:308
#define snprintf
Definition: port.h:238
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322

References ACL_CREATE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, aclnewowner(), Assert, CatalogTupleUpdate(), changeDependencyOnOwner(), check_can_set_role(), DatumGetAclP, DatumGetName(), DatumGetObjectId(), elog, ERROR, get_catalog_object_by_oid(), get_namespace_name(), get_object_attnum_acl(), get_object_attnum_name(), get_object_attnum_namespace(), get_object_attnum_oid(), get_object_attnum_owner(), get_object_type(), GetUserId(), has_privs_of_role(), heap_getattr(), heap_modify_tuple(), InvalidAttrNumber, InvalidOid, InvokeObjectPostAlterHook, NAMEDATALEN, NameStr, object_aclcheck(), OBJECT_SCHEMA, ObjectIdGetDatum(), OidIsValid, palloc0(), pfree(), PointerGetDatum(), RelationGetDescr, RelationGetNumberOfAttributes, RelationGetRelationName, RowExclusiveLock, snprintf, superuser(), HeapTupleData::t_self, table_close(), table_open(), and values.

Referenced by ExecAlterOwnerStmt(), and shdepReassignOwned().

◆ AlterObjectRename_internal()

static void AlterObjectRename_internal ( Relation  rel,
Oid  objectId,
const char *  new_name 
)
static

Definition at line 164 of file alter.c.

165 {
166  Oid classId = RelationGetRelid(rel);
167  int oidCacheId = get_object_catcache_oid(classId);
168  int nameCacheId = get_object_catcache_name(classId);
169  AttrNumber Anum_name = get_object_attnum_name(classId);
170  AttrNumber Anum_namespace = get_object_attnum_namespace(classId);
171  AttrNumber Anum_owner = get_object_attnum_owner(classId);
172  HeapTuple oldtup;
173  HeapTuple newtup;
174  Datum datum;
175  bool isnull;
176  Oid namespaceId;
177  Oid ownerId;
178  char *old_name;
179  AclResult aclresult;
180  Datum *values;
181  bool *nulls;
182  bool *replaces;
183  NameData nameattrdata;
184 
185  oldtup = SearchSysCache1(oidCacheId, ObjectIdGetDatum(objectId));
186  if (!HeapTupleIsValid(oldtup))
187  elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
188  objectId, RelationGetRelationName(rel));
189 
190  datum = heap_getattr(oldtup, Anum_name,
191  RelationGetDescr(rel), &isnull);
192  Assert(!isnull);
193  old_name = NameStr(*(DatumGetName(datum)));
194 
195  /* Get OID of namespace */
196  if (Anum_namespace > 0)
197  {
198  datum = heap_getattr(oldtup, Anum_namespace,
199  RelationGetDescr(rel), &isnull);
200  Assert(!isnull);
201  namespaceId = DatumGetObjectId(datum);
202  }
203  else
204  namespaceId = InvalidOid;
205 
206  /* Permission checks ... superusers can always do it */
207  if (!superuser())
208  {
209  /* Fail if object does not have an explicit owner */
210  if (Anum_owner <= 0)
211  ereport(ERROR,
212  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
213  errmsg("must be superuser to rename %s",
214  getObjectDescriptionOids(classId, objectId))));
215 
216  /* Otherwise, must be owner of the existing object */
217  datum = heap_getattr(oldtup, Anum_owner,
218  RelationGetDescr(rel), &isnull);
219  Assert(!isnull);
220  ownerId = DatumGetObjectId(datum);
221 
222  if (!has_privs_of_role(GetUserId(), DatumGetObjectId(ownerId)))
224  old_name);
225 
226  /* User must have CREATE privilege on the namespace */
227  if (OidIsValid(namespaceId))
228  {
229  aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(),
230  ACL_CREATE);
231  if (aclresult != ACLCHECK_OK)
232  aclcheck_error(aclresult, OBJECT_SCHEMA,
233  get_namespace_name(namespaceId));
234  }
235 
236  if (classId == SubscriptionRelationId)
237  {
239 
240  /* must have CREATE privilege on database */
241  aclresult = object_aclcheck(DatabaseRelationId, MyDatabaseId,
242  GetUserId(), ACL_CREATE);
243  if (aclresult != ACLCHECK_OK)
244  aclcheck_error(aclresult, OBJECT_DATABASE,
246 
247  /*
248  * Don't allow non-superuser modification of a subscription with
249  * password_required=false.
250  */
251  form = (Form_pg_subscription) GETSTRUCT(oldtup);
252  if (!form->subpasswordrequired && !superuser())
253  ereport(ERROR,
254  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
255  errmsg("password_required=false is superuser-only"),
256  errhint("Subscriptions with the password_required option set to false may only be created or modified by the superuser.")));
257  }
258  }
259 
260  /*
261  * Check for duplicate name (more friendly than unique-index failure).
262  * Since this is just a friendliness check, we can just skip it in cases
263  * where there isn't suitable support.
264  */
265  if (classId == ProcedureRelationId)
266  {
267  Form_pg_proc proc = (Form_pg_proc) GETSTRUCT(oldtup);
268 
269  IsThereFunctionInNamespace(new_name, proc->pronargs,
270  &proc->proargtypes, proc->pronamespace);
271  }
272  else if (classId == CollationRelationId)
273  {
275 
276  IsThereCollationInNamespace(new_name, coll->collnamespace);
277  }
278  else if (classId == OperatorClassRelationId)
279  {
280  Form_pg_opclass opc = (Form_pg_opclass) GETSTRUCT(oldtup);
281 
282  IsThereOpClassInNamespace(new_name, opc->opcmethod,
283  opc->opcnamespace);
284  }
285  else if (classId == OperatorFamilyRelationId)
286  {
288 
289  IsThereOpFamilyInNamespace(new_name, opf->opfmethod,
290  opf->opfnamespace);
291  }
292  else if (classId == SubscriptionRelationId)
293  {
294  if (SearchSysCacheExists2(SUBSCRIPTIONNAME,
296  CStringGetDatum(new_name)))
297  report_name_conflict(classId, new_name);
298 
299  /* Also enforce regression testing naming rules, if enabled */
300 #ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS
301  if (strncmp(new_name, "regress_", 8) != 0)
302  elog(WARNING, "subscriptions created by regression test cases should have names starting with \"regress_\"");
303 #endif
304 
305  /* Wake up related replication workers to handle this change quickly */
307  }
308  else if (nameCacheId >= 0)
309  {
310  if (OidIsValid(namespaceId))
311  {
312  if (SearchSysCacheExists2(nameCacheId,
313  CStringGetDatum(new_name),
314  ObjectIdGetDatum(namespaceId)))
315  report_namespace_conflict(classId, new_name, namespaceId);
316  }
317  else
318  {
319  if (SearchSysCacheExists1(nameCacheId,
320  CStringGetDatum(new_name)))
321  report_name_conflict(classId, new_name);
322  }
323  }
324 
325  /* Build modified tuple */
327  nulls = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
328  replaces = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
329  namestrcpy(&nameattrdata, new_name);
330  values[Anum_name - 1] = NameGetDatum(&nameattrdata);
331  replaces[Anum_name - 1] = true;
332  newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel),
333  values, nulls, replaces);
334 
335  /* Perform actual update */
336  CatalogTupleUpdate(rel, &oldtup->t_self, newtup);
337 
338  InvokeObjectPostAlterHook(classId, objectId, 0);
339 
340  /* Release memory */
341  pfree(values);
342  pfree(nulls);
343  pfree(replaces);
344  heap_freetuple(newtup);
345 
346  ReleaseSysCache(oldtup);
347 }
static void report_name_conflict(Oid classId, const char *name)
Definition: alter.c:75
void LogicalRepWorkersWakeupAtCommit(Oid subid)
Definition: worker.c:4989
char * get_database_name(Oid dbid)
Definition: dbcommands.c:3153
int errhint(const char *fmt,...)
Definition: elog.c:1319
#define WARNING
Definition: elog.h:36
Oid MyDatabaseId
Definition: globals.c:91
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1434
void namestrcpy(Name name, const char *str)
Definition: name.c:233
@ OBJECT_DATABASE
Definition: parsenodes.h:2272
FormData_pg_subscription * Form_pg_subscription
static Datum NameGetDatum(const NameData *X)
Definition: postgres.h:373
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
Definition: c.h:741
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:266
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:218
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:95

References ACL_CREATE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, Assert, CatalogTupleUpdate(), CStringGetDatum(), DatumGetName(), DatumGetObjectId(), elog, ereport, errcode(), errhint(), errmsg(), ERROR, get_database_name(), get_namespace_name(), get_object_attnum_name(), get_object_attnum_namespace(), get_object_attnum_owner(), get_object_catcache_name(), get_object_catcache_oid(), get_object_type(), getObjectDescriptionOids(), GETSTRUCT, GetUserId(), has_privs_of_role(), heap_freetuple(), heap_getattr(), heap_modify_tuple(), HeapTupleIsValid, InvalidOid, InvokeObjectPostAlterHook, IsThereCollationInNamespace(), IsThereFunctionInNamespace(), IsThereOpClassInNamespace(), IsThereOpFamilyInNamespace(), LogicalRepWorkersWakeupAtCommit(), MyDatabaseId, NameGetDatum(), NameStr, namestrcpy(), object_aclcheck(), OBJECT_DATABASE, OBJECT_SCHEMA, ObjectIdGetDatum(), OidIsValid, palloc0(), pfree(), RelationGetDescr, RelationGetNumberOfAttributes, RelationGetRelationName, RelationGetRelid, ReleaseSysCache(), report_name_conflict(), report_namespace_conflict(), SearchSysCache1(), SearchSysCacheExists1, SearchSysCacheExists2, superuser(), HeapTupleData::t_self, values, and WARNING.

Referenced by ExecRenameStmt().

◆ ExecAlterObjectDependsStmt()

ObjectAddress ExecAlterObjectDependsStmt ( AlterObjectDependsStmt stmt,
ObjectAddress refAddress 
)

Definition at line 456 of file alter.c.

457 {
458  ObjectAddress address;
459  ObjectAddress refAddr;
460  Relation rel;
461 
462  address =
463  get_object_address_rv(stmt->objectType, stmt->relation, (List *) stmt->object,
464  &rel, AccessExclusiveLock, false);
465 
466  /*
467  * Verify that the user is entitled to run the command.
468  *
469  * We don't check any privileges on the extension, because that's not
470  * needed. The object owner is stipulating, by running this command, that
471  * the extension owner can drop the object whenever they feel like it,
472  * which is not considered a problem.
473  */
475  stmt->objectType, address, stmt->object, rel);
476 
477  /*
478  * If a relation was involved, it would have been opened and locked. We
479  * don't need the relation here, but we'll retain the lock until commit.
480  */
481  if (rel)
482  table_close(rel, NoLock);
483 
484  refAddr = get_object_address(OBJECT_EXTENSION, (Node *) stmt->extname,
485  &rel, AccessExclusiveLock, false);
486  Assert(rel == NULL);
487  if (refAddress)
488  *refAddress = refAddr;
489 
490  if (stmt->remove)
491  {
494  refAddr.classId, refAddr.objectId);
495  }
496  else
497  {
498  List *currexts;
499 
500  /* Avoid duplicates */
501  currexts = getAutoExtensionsOfObject(address.classId,
502  address.objectId);
503  if (!list_member_oid(currexts, refAddr.objectId))
504  recordDependencyOn(&address, &refAddr, DEPENDENCY_AUTO_EXTENSION);
505  }
506 
507  return address;
508 }
@ DEPENDENCY_AUTO_EXTENSION
Definition: dependency.h:39
#define stmt
Definition: indent_codes.h:59
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:722
ObjectAddress get_object_address_rv(ObjectType objtype, RangeVar *rel, List *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
void check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address, Node *object, Relation relation)
ObjectAddress get_object_address(ObjectType objtype, Node *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
@ OBJECT_EXTENSION
Definition: parsenodes.h:2278
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
List * getAutoExtensionsOfObject(Oid classId, Oid objectId)
Definition: pg_depend.c:777
long deleteDependencyRecordsForSpecific(Oid classId, Oid objectId, char deptype, Oid refclassId, Oid refobjectId)
Definition: pg_depend.c:397
Definition: pg_list.h:54
Definition: nodes.h:129

References AccessExclusiveLock, Assert, check_object_ownership(), ObjectAddress::classId, deleteDependencyRecordsForSpecific(), DEPENDENCY_AUTO_EXTENSION, get_object_address(), get_object_address_rv(), getAutoExtensionsOfObject(), GetUserId(), list_member_oid(), NoLock, OBJECT_EXTENSION, ObjectAddress::objectId, recordDependencyOn(), stmt, and table_close().

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

◆ ExecAlterObjectSchemaStmt()

ObjectAddress ExecAlterObjectSchemaStmt ( AlterObjectSchemaStmt stmt,
ObjectAddress oldSchemaAddr 
)

Definition at line 520 of file alter.c.

522 {
523  ObjectAddress address;
524  Oid oldNspOid;
525 
526  switch (stmt->objectType)
527  {
528  case OBJECT_EXTENSION:
529  address = AlterExtensionNamespace(strVal(stmt->object), stmt->newschema,
530  oldSchemaAddr ? &oldNspOid : NULL);
531  break;
532 
534  case OBJECT_SEQUENCE:
535  case OBJECT_TABLE:
536  case OBJECT_VIEW:
537  case OBJECT_MATVIEW:
538  address = AlterTableNamespace(stmt,
539  oldSchemaAddr ? &oldNspOid : NULL);
540  break;
541 
542  case OBJECT_DOMAIN:
543  case OBJECT_TYPE:
544  address = AlterTypeNamespace(castNode(List, stmt->object), stmt->newschema,
545  stmt->objectType,
546  oldSchemaAddr ? &oldNspOid : NULL);
547  break;
548 
549  /* generic code path */
550  case OBJECT_AGGREGATE:
551  case OBJECT_COLLATION:
552  case OBJECT_CONVERSION:
553  case OBJECT_FUNCTION:
554  case OBJECT_OPERATOR:
555  case OBJECT_OPCLASS:
556  case OBJECT_OPFAMILY:
557  case OBJECT_PROCEDURE:
558  case OBJECT_ROUTINE:
561  case OBJECT_TSDICTIONARY:
562  case OBJECT_TSPARSER:
563  case OBJECT_TSTEMPLATE:
564  {
565  Relation catalog;
566  Relation relation;
567  Oid classId;
568  Oid nspOid;
569 
570  address = get_object_address(stmt->objectType,
571  stmt->object,
572  &relation,
574  false);
575  Assert(relation == NULL);
576  classId = address.classId;
577  catalog = table_open(classId, RowExclusiveLock);
578  nspOid = LookupCreationNamespace(stmt->newschema);
579 
580  oldNspOid = AlterObjectNamespace_internal(catalog, address.objectId,
581  nspOid);
582  table_close(catalog, RowExclusiveLock);
583  }
584  break;
585 
586  default:
587  elog(ERROR, "unrecognized AlterObjectSchemaStmt type: %d",
588  (int) stmt->objectType);
589  return InvalidObjectAddress; /* keep compiler happy */
590  }
591 
592  if (oldSchemaAddr)
593  ObjectAddressSet(*oldSchemaAddr, NamespaceRelationId, oldNspOid);
594 
595  return address;
596 }
ObjectAddress AlterExtensionNamespace(const char *extensionName, const char *newschema, Oid *oldschema)
Definition: extension.c:2772
Oid LookupCreationNamespace(const char *nspname)
Definition: namespace.c:3413
#define castNode(_type_, nodeptr)
Definition: nodes.h:176
const ObjectAddress InvalidObjectAddress
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
@ OBJECT_TSPARSER
Definition: parsenodes.h:2310
@ OBJECT_COLLATION
Definition: parsenodes.h:2270
@ OBJECT_OPCLASS
Definition: parsenodes.h:2287
@ OBJECT_AGGREGATE
Definition: parsenodes.h:2264
@ OBJECT_MATVIEW
Definition: parsenodes.h:2286
@ OBJECT_OPERATOR
Definition: parsenodes.h:2288
@ OBJECT_FOREIGN_TABLE
Definition: parsenodes.h:2281
@ OBJECT_TSCONFIGURATION
Definition: parsenodes.h:2308
@ OBJECT_OPFAMILY
Definition: parsenodes.h:2289
@ OBJECT_DOMAIN
Definition: parsenodes.h:2275
@ OBJECT_ROUTINE
Definition: parsenodes.h:2297
@ OBJECT_PROCEDURE
Definition: parsenodes.h:2292
@ OBJECT_SEQUENCE
Definition: parsenodes.h:2300
@ OBJECT_TSTEMPLATE
Definition: parsenodes.h:2311
@ OBJECT_TSDICTIONARY
Definition: parsenodes.h:2309
@ OBJECT_CONVERSION
Definition: parsenodes.h:2271
@ OBJECT_TABLE
Definition: parsenodes.h:2304
@ OBJECT_VIEW
Definition: parsenodes.h:2314
@ OBJECT_TYPE
Definition: parsenodes.h:2312
@ OBJECT_FUNCTION
Definition: parsenodes.h:2282
@ OBJECT_STATISTIC_EXT
Definition: parsenodes.h:2302
ObjectAddress AlterTableNamespace(AlterObjectSchemaStmt *stmt, Oid *oldschema)
Definition: tablecmds.c:17876
ObjectAddress AlterTypeNamespace(List *names, const char *newschema, ObjectType objecttype, Oid *oldschema)
Definition: typecmds.c:4057
#define strVal(v)
Definition: value.h:82

References AccessExclusiveLock, AlterExtensionNamespace(), AlterObjectNamespace_internal(), AlterTableNamespace(), AlterTypeNamespace(), Assert, castNode, ObjectAddress::classId, elog, ERROR, get_object_address(), InvalidObjectAddress, LookupCreationNamespace(), OBJECT_AGGREGATE, OBJECT_COLLATION, OBJECT_CONVERSION, OBJECT_DOMAIN, OBJECT_EXTENSION, OBJECT_FOREIGN_TABLE, OBJECT_FUNCTION, OBJECT_MATVIEW, OBJECT_OPCLASS, OBJECT_OPERATOR, OBJECT_OPFAMILY, OBJECT_PROCEDURE, OBJECT_ROUTINE, OBJECT_SEQUENCE, OBJECT_STATISTIC_EXT, OBJECT_TABLE, OBJECT_TSCONFIGURATION, OBJECT_TSDICTIONARY, OBJECT_TSPARSER, OBJECT_TSTEMPLATE, OBJECT_TYPE, OBJECT_VIEW, ObjectAddressSet, ObjectAddress::objectId, RowExclusiveLock, stmt, strVal, table_close(), and table_open().

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

◆ ExecAlterOwnerStmt()

ObjectAddress ExecAlterOwnerStmt ( AlterOwnerStmt stmt)

Definition at line 825 of file alter.c.

826 {
827  Oid newowner = get_rolespec_oid(stmt->newowner, false);
828 
829  switch (stmt->objectType)
830  {
831  case OBJECT_DATABASE:
832  return AlterDatabaseOwner(strVal(stmt->object), newowner);
833 
834  case OBJECT_SCHEMA:
835  return AlterSchemaOwner(strVal(stmt->object), newowner);
836 
837  case OBJECT_TYPE:
838  case OBJECT_DOMAIN: /* same as TYPE */
839  return AlterTypeOwner(castNode(List, stmt->object), newowner, stmt->objectType);
840  break;
841 
842  case OBJECT_FDW:
843  return AlterForeignDataWrapperOwner(strVal(stmt->object),
844  newowner);
845 
847  return AlterForeignServerOwner(strVal(stmt->object),
848  newowner);
849 
851  return AlterEventTriggerOwner(strVal(stmt->object),
852  newowner);
853 
854  case OBJECT_PUBLICATION:
855  return AlterPublicationOwner(strVal(stmt->object),
856  newowner);
857 
858  case OBJECT_SUBSCRIPTION:
859  return AlterSubscriptionOwner(strVal(stmt->object),
860  newowner);
861 
862  /* Generic cases */
863  case OBJECT_AGGREGATE:
864  case OBJECT_COLLATION:
865  case OBJECT_CONVERSION:
866  case OBJECT_FUNCTION:
867  case OBJECT_LANGUAGE:
868  case OBJECT_LARGEOBJECT:
869  case OBJECT_OPERATOR:
870  case OBJECT_OPCLASS:
871  case OBJECT_OPFAMILY:
872  case OBJECT_PROCEDURE:
873  case OBJECT_ROUTINE:
875  case OBJECT_TABLESPACE:
876  case OBJECT_TSDICTIONARY:
878  {
879  Relation relation;
880  ObjectAddress address;
881 
882  address = get_object_address(stmt->objectType,
883  stmt->object,
884  &relation,
886  false);
887  Assert(relation == NULL);
888 
889  AlterObjectOwner_internal(address.classId, address.objectId,
890  newowner);
891 
892  return address;
893  }
894  break;
895 
896  default:
897  elog(ERROR, "unrecognized AlterOwnerStmt type: %d",
898  (int) stmt->objectType);
899  return InvalidObjectAddress; /* keep compiler happy */
900  }
901 }
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5448
void AlterObjectOwner_internal(Oid classId, Oid objectId, Oid new_ownerId)
Definition: alter.c:916
ObjectAddress AlterDatabaseOwner(const char *dbname, Oid newOwnerId)
Definition: dbcommands.c:2606
ObjectAddress AlterEventTriggerOwner(const char *name, Oid newOwnerId)
ObjectAddress AlterForeignServerOwner(const char *name, Oid newOwnerId)
Definition: foreigncmds.c:415
ObjectAddress AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
Definition: foreigncmds.c:275
@ OBJECT_EVENT_TRIGGER
Definition: parsenodes.h:2277
@ OBJECT_FDW
Definition: parsenodes.h:2279
@ OBJECT_TABLESPACE
Definition: parsenodes.h:2305
@ OBJECT_LARGEOBJECT
Definition: parsenodes.h:2285
@ OBJECT_LANGUAGE
Definition: parsenodes.h:2284
@ OBJECT_FOREIGN_SERVER
Definition: parsenodes.h:2280
@ OBJECT_PUBLICATION
Definition: parsenodes.h:2293
@ OBJECT_SUBSCRIPTION
Definition: parsenodes.h:2301
ObjectAddress AlterPublicationOwner(const char *name, Oid newOwnerId)
ObjectAddress AlterSchemaOwner(const char *name, Oid newOwnerId)
Definition: schemacmds.c:330
ObjectAddress AlterSubscriptionOwner(const char *name, Oid newOwnerId)
ObjectAddress AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype)
Definition: typecmds.c:3824

References AccessExclusiveLock, AlterDatabaseOwner(), AlterEventTriggerOwner(), AlterForeignDataWrapperOwner(), AlterForeignServerOwner(), AlterObjectOwner_internal(), AlterPublicationOwner(), AlterSchemaOwner(), AlterSubscriptionOwner(), AlterTypeOwner(), Assert, castNode, ObjectAddress::classId, elog, ERROR, get_object_address(), get_rolespec_oid(), InvalidObjectAddress, OBJECT_AGGREGATE, OBJECT_COLLATION, OBJECT_CONVERSION, OBJECT_DATABASE, OBJECT_DOMAIN, OBJECT_EVENT_TRIGGER, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FUNCTION, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_OPCLASS, OBJECT_OPERATOR, OBJECT_OPFAMILY, OBJECT_PROCEDURE, OBJECT_PUBLICATION, OBJECT_ROUTINE, OBJECT_SCHEMA, OBJECT_STATISTIC_EXT, OBJECT_SUBSCRIPTION, OBJECT_TABLESPACE, OBJECT_TSCONFIGURATION, OBJECT_TSDICTIONARY, OBJECT_TYPE, ObjectAddress::objectId, stmt, and strVal.

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

◆ ExecRenameStmt()

ObjectAddress ExecRenameStmt ( RenameStmt stmt)

Definition at line 356 of file alter.c.

357 {
358  switch (stmt->renameType)
359  {
362  return RenameConstraint(stmt);
363 
364  case OBJECT_DATABASE:
365  return RenameDatabase(stmt->subname, stmt->newname);
366 
367  case OBJECT_ROLE:
368  return RenameRole(stmt->subname, stmt->newname);
369 
370  case OBJECT_SCHEMA:
371  return RenameSchema(stmt->subname, stmt->newname);
372 
373  case OBJECT_TABLESPACE:
374  return RenameTableSpace(stmt->subname, stmt->newname);
375 
376  case OBJECT_TABLE:
377  case OBJECT_SEQUENCE:
378  case OBJECT_VIEW:
379  case OBJECT_MATVIEW:
380  case OBJECT_INDEX:
382  return RenameRelation(stmt);
383 
384  case OBJECT_COLUMN:
385  case OBJECT_ATTRIBUTE:
386  return renameatt(stmt);
387 
388  case OBJECT_RULE:
389  return RenameRewriteRule(stmt->relation, stmt->subname,
390  stmt->newname);
391 
392  case OBJECT_TRIGGER:
393  return renametrig(stmt);
394 
395  case OBJECT_POLICY:
396  return rename_policy(stmt);
397 
398  case OBJECT_DOMAIN:
399  case OBJECT_TYPE:
400  return RenameType(stmt);
401 
402  case OBJECT_AGGREGATE:
403  case OBJECT_COLLATION:
404  case OBJECT_CONVERSION:
406  case OBJECT_FDW:
408  case OBJECT_FUNCTION:
409  case OBJECT_OPCLASS:
410  case OBJECT_OPFAMILY:
411  case OBJECT_LANGUAGE:
412  case OBJECT_PROCEDURE:
413  case OBJECT_ROUTINE:
416  case OBJECT_TSDICTIONARY:
417  case OBJECT_TSPARSER:
418  case OBJECT_TSTEMPLATE:
419  case OBJECT_PUBLICATION:
420  case OBJECT_SUBSCRIPTION:
421  {
422  ObjectAddress address;
423  Relation catalog;
424  Relation relation;
425 
426  address = get_object_address(stmt->renameType,
427  stmt->object,
428  &relation,
429  AccessExclusiveLock, false);
430  Assert(relation == NULL);
431 
432  catalog = table_open(address.classId, RowExclusiveLock);
434  address.objectId,
435  stmt->newname);
436  table_close(catalog, RowExclusiveLock);
437 
438  return address;
439  }
440 
441  default:
442  elog(ERROR, "unrecognized rename stmt type: %d",
443  (int) stmt->renameType);
444  return InvalidObjectAddress; /* keep compiler happy */
445  }
446 }
static void AlterObjectRename_internal(Relation rel, Oid objectId, const char *new_name)
Definition: alter.c:164
ObjectAddress RenameTableSpace(const char *oldname, const char *newname)
Definition: tablespace.c:930
ObjectAddress RenameRole(const char *oldname, const char *newname)
Definition: user.c:1334
ObjectAddress RenameDatabase(const char *oldname, const char *newname)
Definition: dbcommands.c:1855
@ OBJECT_POLICY
Definition: parsenodes.h:2291
@ OBJECT_COLUMN
Definition: parsenodes.h:2269
@ OBJECT_ROLE
Definition: parsenodes.h:2296
@ OBJECT_INDEX
Definition: parsenodes.h:2283
@ OBJECT_ATTRIBUTE
Definition: parsenodes.h:2267
@ OBJECT_RULE
Definition: parsenodes.h:2298
@ OBJECT_TABCONSTRAINT
Definition: parsenodes.h:2303
@ OBJECT_DOMCONSTRAINT
Definition: parsenodes.h:2276
@ OBJECT_TRIGGER
Definition: parsenodes.h:2307
ObjectAddress rename_policy(RenameStmt *stmt)
Definition: policy.c:1096
ObjectAddress RenameRewriteRule(RangeVar *relation, const char *oldName, const char *newName)
ObjectAddress RenameSchema(const char *oldname, const char *newname)
Definition: schemacmds.c:249
ObjectAddress RenameRelation(RenameStmt *stmt)
Definition: tablecmds.c:4139
ObjectAddress renameatt(RenameStmt *stmt)
Definition: tablecmds.c:3942
ObjectAddress RenameConstraint(RenameStmt *stmt)
Definition: tablecmds.c:4089
ObjectAddress renametrig(RenameStmt *stmt)
Definition: trigger.c:1463
ObjectAddress RenameType(RenameStmt *stmt)
Definition: typecmds.c:3743

References AccessExclusiveLock, AlterObjectRename_internal(), Assert, ObjectAddress::classId, elog, ERROR, get_object_address(), InvalidObjectAddress, OBJECT_AGGREGATE, OBJECT_ATTRIBUTE, OBJECT_COLLATION, OBJECT_COLUMN, OBJECT_CONVERSION, OBJECT_DATABASE, OBJECT_DOMAIN, OBJECT_DOMCONSTRAINT, OBJECT_EVENT_TRIGGER, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FOREIGN_TABLE, OBJECT_FUNCTION, OBJECT_INDEX, OBJECT_LANGUAGE, OBJECT_MATVIEW, OBJECT_OPCLASS, OBJECT_OPFAMILY, OBJECT_POLICY, OBJECT_PROCEDURE, OBJECT_PUBLICATION, OBJECT_ROLE, OBJECT_ROUTINE, OBJECT_RULE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_STATISTIC_EXT, OBJECT_SUBSCRIPTION, OBJECT_TABCONSTRAINT, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TRIGGER, OBJECT_TSCONFIGURATION, OBJECT_TSDICTIONARY, OBJECT_TSPARSER, OBJECT_TSTEMPLATE, OBJECT_TYPE, OBJECT_VIEW, ObjectAddress::objectId, rename_policy(), renameatt(), RenameConstraint(), RenameDatabase(), RenameRelation(), RenameRewriteRule(), RenameRole(), RenameSchema(), RenameTableSpace(), renametrig(), RenameType(), RowExclusiveLock, stmt, table_close(), and table_open().

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

◆ report_name_conflict()

static void report_name_conflict ( Oid  classId,
const char *  name 
)
static

Definition at line 75 of file alter.c.

76 {
77  char *msgfmt;
78 
79  switch (classId)
80  {
81  case EventTriggerRelationId:
82  msgfmt = gettext_noop("event trigger \"%s\" already exists");
83  break;
84  case ForeignDataWrapperRelationId:
85  msgfmt = gettext_noop("foreign-data wrapper \"%s\" already exists");
86  break;
87  case ForeignServerRelationId:
88  msgfmt = gettext_noop("server \"%s\" already exists");
89  break;
90  case LanguageRelationId:
91  msgfmt = gettext_noop("language \"%s\" already exists");
92  break;
93  case PublicationRelationId:
94  msgfmt = gettext_noop("publication \"%s\" already exists");
95  break;
96  case SubscriptionRelationId:
97  msgfmt = gettext_noop("subscription \"%s\" already exists");
98  break;
99  default:
100  elog(ERROR, "unsupported object class: %u", classId);
101  break;
102  }
103 
104  ereport(ERROR,
106  errmsg(msgfmt, name)));
107 }
#define gettext_noop(x)
Definition: c.h:1196
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:32

References elog, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, gettext_noop, and name.

Referenced by AlterObjectRename_internal().

◆ report_namespace_conflict()

static void report_namespace_conflict ( Oid  classId,
const char *  name,
Oid  nspOid 
)
static

Definition at line 110 of file alter.c.

111 {
112  char *msgfmt;
113 
114  Assert(OidIsValid(nspOid));
115 
116  switch (classId)
117  {
118  case ConversionRelationId:
119  Assert(OidIsValid(nspOid));
120  msgfmt = gettext_noop("conversion \"%s\" already exists in schema \"%s\"");
121  break;
122  case StatisticExtRelationId:
123  Assert(OidIsValid(nspOid));
124  msgfmt = gettext_noop("statistics object \"%s\" already exists in schema \"%s\"");
125  break;
126  case TSParserRelationId:
127  Assert(OidIsValid(nspOid));
128  msgfmt = gettext_noop("text search parser \"%s\" already exists in schema \"%s\"");
129  break;
130  case TSDictionaryRelationId:
131  Assert(OidIsValid(nspOid));
132  msgfmt = gettext_noop("text search dictionary \"%s\" already exists in schema \"%s\"");
133  break;
134  case TSTemplateRelationId:
135  Assert(OidIsValid(nspOid));
136  msgfmt = gettext_noop("text search template \"%s\" already exists in schema \"%s\"");
137  break;
138  case TSConfigRelationId:
139  Assert(OidIsValid(nspOid));
140  msgfmt = gettext_noop("text search configuration \"%s\" already exists in schema \"%s\"");
141  break;
142  default:
143  elog(ERROR, "unsupported object class: %u", classId);
144  break;
145  }
146 
147  ereport(ERROR,
149  errmsg(msgfmt, name, get_namespace_name(nspOid))));
150 }

References Assert, elog, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, get_namespace_name(), gettext_noop, name, and OidIsValid.

Referenced by AlterObjectNamespace_internal(), and AlterObjectRename_internal().