PostgreSQL Source Code  git master
alter.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/relation.h"
#include "access/sysattr.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_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_opfamily.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_subscription.h"
#include "catalog/pg_statistic_ext.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/conversioncmds.h"
#include "commands/dbcommands.h"
#include "commands/defrem.h"
#include "commands/event_trigger.h"
#include "commands/extension.h"
#include "commands/policy.h"
#include "commands/proclang.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 "parser/parse_func.h"
#include "miscadmin.h"
#include "rewrite/rewriteDefine.h"
#include "tcop/utility.h"
#include "utils/builtins.h"
#include "utils/fmgroids.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 (Relation rel, Oid objectId, Oid new_ownerId)
 

Function Documentation

◆ AlterObjectNamespace_internal()

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

Definition at line 665 of file alter.c.

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_SCHEMA, ObjectIdGetDatum, palloc0(), pfree(), pg_namespace_aclcheck(), RelationGetDescr, RelationGetNumberOfAttributes, RelationGetRelationName, RelationGetRelid, report_namespace_conflict(), SearchSysCacheCopy1, SearchSysCacheExists2, superuser(), and values.

Referenced by AlterObjectNamespace_oid(), and ExecAlterObjectSchemaStmt().

666 {
667  Oid classId = RelationGetRelid(rel);
668  int oidCacheId = get_object_catcache_oid(classId);
669  int nameCacheId = get_object_catcache_name(classId);
670  AttrNumber Anum_name = get_object_attnum_name(classId);
671  AttrNumber Anum_namespace = get_object_attnum_namespace(classId);
672  AttrNumber Anum_owner = get_object_attnum_owner(classId);
673  ObjectType objtype = get_object_type(classId, objid);
674  Oid oldNspOid;
675  Datum name,
676  namespace;
677  bool isnull;
678  HeapTuple tup,
679  newtup;
680  Datum *values;
681  bool *nulls;
682  bool *replaces;
683 
684  tup = SearchSysCacheCopy1(oidCacheId, ObjectIdGetDatum(objid));
685  if (!HeapTupleIsValid(tup)) /* should not happen */
686  elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
687  objid, RelationGetRelationName(rel));
688 
689  name = heap_getattr(tup, Anum_name, RelationGetDescr(rel), &isnull);
690  Assert(!isnull);
691  namespace = heap_getattr(tup, Anum_namespace, RelationGetDescr(rel),
692  &isnull);
693  Assert(!isnull);
694  oldNspOid = DatumGetObjectId(namespace);
695 
696  /*
697  * If the object is already in the correct namespace, we don't need to do
698  * anything except fire the object access hook.
699  */
700  if (oldNspOid == nspOid)
701  {
702  InvokeObjectPostAlterHook(classId, objid, 0);
703  return oldNspOid;
704  }
705 
706  /* Check basic namespace related issues */
707  CheckSetNamespace(oldNspOid, nspOid);
708 
709  /* Permission checks ... superusers can always do it */
710  if (!superuser())
711  {
712  Datum owner;
713  Oid ownerId;
714  AclResult aclresult;
715 
716  /* Fail if object does not have an explicit owner */
717  if (Anum_owner <= 0)
718  ereport(ERROR,
719  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
720  (errmsg("must be superuser to set schema of %s",
721  getObjectDescriptionOids(classId, objid)))));
722 
723  /* Otherwise, must be owner of the existing object */
724  owner = heap_getattr(tup, Anum_owner, RelationGetDescr(rel), &isnull);
725  Assert(!isnull);
726  ownerId = DatumGetObjectId(owner);
727 
728  if (!has_privs_of_role(GetUserId(), ownerId))
730  NameStr(*(DatumGetName(name))));
731 
732  /* User must have CREATE privilege on new namespace */
733  aclresult = pg_namespace_aclcheck(nspOid, GetUserId(), ACL_CREATE);
734  if (aclresult != ACLCHECK_OK)
735  aclcheck_error(aclresult, OBJECT_SCHEMA,
736  get_namespace_name(nspOid));
737  }
738 
739  /*
740  * Check for duplicate name (more friendly than unique-index failure).
741  * Since this is just a friendliness check, we can just skip it in cases
742  * where there isn't suitable support.
743  */
744  if (classId == ProcedureRelationId)
745  {
746  Form_pg_proc proc = (Form_pg_proc) GETSTRUCT(tup);
747 
748  IsThereFunctionInNamespace(NameStr(proc->proname), proc->pronargs,
749  &proc->proargtypes, nspOid);
750  }
751  else if (classId == CollationRelationId)
752  {
754 
755  IsThereCollationInNamespace(NameStr(coll->collname), nspOid);
756  }
757  else if (classId == OperatorClassRelationId)
758  {
760 
761  IsThereOpClassInNamespace(NameStr(opc->opcname),
762  opc->opcmethod, nspOid);
763  }
764  else if (classId == OperatorFamilyRelationId)
765  {
767 
768  IsThereOpFamilyInNamespace(NameStr(opf->opfname),
769  opf->opfmethod, nspOid);
770  }
771  else if (nameCacheId >= 0 &&
772  SearchSysCacheExists2(nameCacheId, name,
773  ObjectIdGetDatum(nspOid)))
775  NameStr(*(DatumGetName(name))),
776  nspOid);
777 
778  /* Build modified tuple */
779  values = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(Datum));
780  nulls = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
781  replaces = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
782  values[Anum_namespace - 1] = ObjectIdGetDatum(nspOid);
783  replaces[Anum_namespace - 1] = true;
784  newtup = heap_modify_tuple(tup, RelationGetDescr(rel),
785  values, nulls, replaces);
786 
787  /* Perform actual update */
788  CatalogTupleUpdate(rel, &tup->t_self, newtup);
789 
790  /* Release memory */
791  pfree(values);
792  pfree(nulls);
793  pfree(replaces);
794 
795  /* update dependencies to point to the new schema */
796  changeDependencyFor(classId, objid,
797  NamespaceRelationId, oldNspOid, nspOid);
798 
799  InvokeObjectPostAlterHook(classId, objid, 0);
800 
801  return oldNspOid;
802 }
static void report_namespace_conflict(Oid classId, const char *name, Oid nspOid)
Definition: alter.c:113
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
AttrNumber get_object_attnum_owner(Oid class_id)
#define RelationGetDescr(relation)
Definition: rel.h:442
Oid GetUserId(void)
Definition: miscinit.c:380
#define RelationGetNumberOfAttributes(relation)
Definition: rel.h:422
#define DatumGetObjectId(X)
Definition: postgres.h:500
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4908
int get_object_catcache_name(Oid class_id)
int errcode(int sqlerrcode)
Definition: elog.c:570
bool superuser(void)
Definition: superuser.c:47
AttrNumber get_object_attnum_namespace(Oid class_id)
unsigned int Oid
Definition: postgres_ext.h:31
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4693
void IsThereOpClassInNamespace(const char *opcname, Oid opcmethod, Oid opcnamespace)
Definition: opclasscmds.c:1706
#define DatumGetName(X)
Definition: postgres.h:585
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3353
void pfree(void *pointer)
Definition: mcxt.c:1031
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ACL_CREATE
Definition: parsenodes.h:84
int get_object_catcache_oid(Oid class_id)
ItemPointerData t_self
Definition: htup.h:65
char * getObjectDescriptionOids(Oid classid, Oid objid)
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3094
#define RelationGetRelationName(relation)
Definition: rel.h:450
void IsThereCollationInNamespace(const char *collname, Oid nspOid)
#define ereport(elevel, rest)
Definition: elog.h:141
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
ObjectType
Definition: parsenodes.h:1669
void CheckSetNamespace(Oid oldNspOid, Oid nspOid)
Definition: namespace.c:2959
void IsThereFunctionInNamespace(const char *proname, int pronargs, oidvector *proargtypes, Oid nspOid)
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:762
FormData_pg_opfamily * Form_pg_opfamily
Definition: pg_opfamily.h:51
AttrNumber get_object_attnum_name(Oid class_id)
void * palloc0(Size size)
Definition: mcxt.c:955
AclResult
Definition: acl.h:177
uintptr_t Datum
Definition: postgres.h:367
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:134
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Assert(condition)
Definition: c.h:732
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:224
ObjectType get_object_type(Oid class_id, Oid object_id)
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:185
const char * name
Definition: encode.c:521
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:51
static Datum values[MAXATTR]
Definition: bootstrap.c:167
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:174
int errmsg(const char *fmt,...)
Definition: elog.c:784
long changeDependencyFor(Oid classId, Oid objectId, Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId)
Definition: pg_depend.c:297
#define elog(elevel,...)
Definition: elog.h:226
#define NameStr(name)
Definition: c.h:609
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:1113
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:83
int16 AttrNumber
Definition: attnum.h:21
#define RelationGetRelid(relation)
Definition: rel.h:416
void IsThereOpFamilyInNamespace(const char *opfname, Oid opfmethod, Oid opfnamespace)
Definition: opclasscmds.c:1729

◆ AlterObjectNamespace_oid()

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

Definition at line 564 of file alter.c.

References AccessExclusiveLock, AlterObjectNamespace_internal(), AlterTableNamespaceInternal(), AlterTypeNamespace_oid(), ObjectAddress::classId, getObjectClass(), InvalidOid, NoLock, ObjectAddress::objectId, ObjectAddress::objectSubId, OCLASS_AM, OCLASS_AMOP, OCLASS_AMPROC, OCLASS_CAST, OCLASS_CLASS, OCLASS_COLLATION, OCLASS_CONSTRAINT, OCLASS_CONVERSION, OCLASS_DATABASE, OCLASS_DEFACL, OCLASS_DEFAULT, OCLASS_EVENT_TRIGGER, OCLASS_EXTENSION, OCLASS_FDW, OCLASS_FOREIGN_SERVER, OCLASS_LANGUAGE, OCLASS_LARGEOBJECT, OCLASS_OPCLASS, OCLASS_OPERATOR, OCLASS_OPFAMILY, OCLASS_POLICY, OCLASS_PROC, OCLASS_PUBLICATION, OCLASS_PUBLICATION_REL, OCLASS_REWRITE, OCLASS_ROLE, OCLASS_SCHEMA, OCLASS_STATISTIC_EXT, OCLASS_SUBSCRIPTION, OCLASS_TBLSPACE, OCLASS_TRANSFORM, OCLASS_TRIGGER, OCLASS_TSCONFIG, OCLASS_TSDICT, OCLASS_TSPARSER, OCLASS_TSTEMPLATE, OCLASS_TYPE, OCLASS_USER_MAPPING, relation_close(), relation_open(), RelationGetNamespace, RowExclusiveLock, table_close(), and table_open().

Referenced by AlterExtensionNamespace().

566 {
567  Oid oldNspOid = InvalidOid;
568  ObjectAddress dep;
569 
570  dep.classId = classId;
571  dep.objectId = objid;
572  dep.objectSubId = 0;
573 
574  switch (getObjectClass(&dep))
575  {
576  case OCLASS_CLASS:
577  {
578  Relation rel;
579 
580  rel = relation_open(objid, AccessExclusiveLock);
581  oldNspOid = RelationGetNamespace(rel);
582 
583  AlterTableNamespaceInternal(rel, oldNspOid, nspOid, objsMoved);
584 
585  relation_close(rel, NoLock);
586  break;
587  }
588 
589  case OCLASS_TYPE:
590  oldNspOid = AlterTypeNamespace_oid(objid, nspOid, objsMoved);
591  break;
592 
593  case OCLASS_PROC:
594  case OCLASS_COLLATION:
595  case OCLASS_CONVERSION:
596  case OCLASS_OPERATOR:
597  case OCLASS_OPCLASS:
598  case OCLASS_OPFAMILY:
600  case OCLASS_TSPARSER:
601  case OCLASS_TSDICT:
602  case OCLASS_TSTEMPLATE:
603  case OCLASS_TSCONFIG:
604  {
605  Relation catalog;
606 
607  catalog = table_open(classId, RowExclusiveLock);
608 
609  oldNspOid = AlterObjectNamespace_internal(catalog, objid,
610  nspOid);
611 
612  table_close(catalog, RowExclusiveLock);
613  }
614  break;
615 
616  case OCLASS_CAST:
617  case OCLASS_CONSTRAINT:
618  case OCLASS_DEFAULT:
619  case OCLASS_LANGUAGE:
620  case OCLASS_LARGEOBJECT:
621  case OCLASS_AM:
622  case OCLASS_AMOP:
623  case OCLASS_AMPROC:
624  case OCLASS_REWRITE:
625  case OCLASS_TRIGGER:
626  case OCLASS_SCHEMA:
627  case OCLASS_ROLE:
628  case OCLASS_DATABASE:
629  case OCLASS_TBLSPACE:
630  case OCLASS_FDW:
632  case OCLASS_USER_MAPPING:
633  case OCLASS_DEFACL:
634  case OCLASS_EXTENSION:
636  case OCLASS_POLICY:
637  case OCLASS_PUBLICATION:
639  case OCLASS_SUBSCRIPTION:
640  case OCLASS_TRANSFORM:
641  /* ignore object types that don't have schema-qualified names */
642  break;
643 
644  /*
645  * There's intentionally no default: case here; we want the
646  * compiler to warn if a new OCLASS hasn't been handled above.
647  */
648  }
649 
650  return oldNspOid;
651 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
static Oid AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
Definition: alter.c:665
unsigned int Oid
Definition: postgres_ext.h:31
ObjectClass getObjectClass(const ObjectAddress *object)
Definition: dependency.c:2695
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: relation.c:48
void AlterTableNamespaceInternal(Relation rel, Oid oldNspOid, Oid nspOid, ObjectAddresses *objsMoved)
Definition: tablecmds.c:14254
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
Oid AlterTypeNamespace_oid(Oid typeOid, Oid nspOid, ObjectAddresses *objsMoved)
Definition: typecmds.c:3541
#define InvalidOid
Definition: postgres_ext.h:36
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: relation.c:206
#define AccessExclusiveLock
Definition: lockdefs.h:45
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define RelationGetNamespace(relation)
Definition: rel.h:457

◆ AlterObjectOwner_internal()

void AlterObjectOwner_internal ( Relation  rel,
Oid  objectId,
Oid  new_ownerId 
)

Definition at line 910 of file alter.c.

References ACL_CREATE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, aclnewowner(), Assert, CatalogTupleUpdate(), changeDependencyOnOwner(), check_is_member_of_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_SCHEMA, ObjectIdGetDatum, OidIsValid, palloc0(), pfree(), pg_namespace_aclcheck(), PointerGetDatum, RelationGetDescr, RelationGetNumberOfAttributes, RelationGetRelationName, RelationGetRelid, snprintf, superuser(), HeapTupleData::t_self, and values.

Referenced by ExecAlterOwnerStmt(), and shdepReassignOwned().

911 {
912  Oid classId = RelationGetRelid(rel);
913  AttrNumber Anum_oid = get_object_attnum_oid(classId);
914  AttrNumber Anum_owner = get_object_attnum_owner(classId);
915  AttrNumber Anum_namespace = get_object_attnum_namespace(classId);
916  AttrNumber Anum_acl = get_object_attnum_acl(classId);
917  AttrNumber Anum_name = get_object_attnum_name(classId);
918  HeapTuple oldtup;
919  Datum datum;
920  bool isnull;
921  Oid old_ownerId;
922  Oid namespaceId = InvalidOid;
923 
924  oldtup = get_catalog_object_by_oid(rel, Anum_oid, objectId);
925  if (oldtup == NULL)
926  elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
927  objectId, RelationGetRelationName(rel));
928 
929  datum = heap_getattr(oldtup, Anum_owner,
930  RelationGetDescr(rel), &isnull);
931  Assert(!isnull);
932  old_ownerId = DatumGetObjectId(datum);
933 
934  if (Anum_namespace != InvalidAttrNumber)
935  {
936  datum = heap_getattr(oldtup, Anum_namespace,
937  RelationGetDescr(rel), &isnull);
938  Assert(!isnull);
939  namespaceId = DatumGetObjectId(datum);
940  }
941 
942  if (old_ownerId != new_ownerId)
943  {
944  AttrNumber nattrs;
945  HeapTuple newtup;
946  Datum *values;
947  bool *nulls;
948  bool *replaces;
949 
950  /* Superusers can bypass permission checks */
951  if (!superuser())
952  {
953  ObjectType objtype = get_object_type(classId, objectId);
954 
955  /* must be owner */
956  if (!has_privs_of_role(GetUserId(), old_ownerId))
957  {
958  char *objname;
959  char namebuf[NAMEDATALEN];
960 
961  if (Anum_name != InvalidAttrNumber)
962  {
963  datum = heap_getattr(oldtup, Anum_name,
964  RelationGetDescr(rel), &isnull);
965  Assert(!isnull);
966  objname = NameStr(*DatumGetName(datum));
967  }
968  else
969  {
970  snprintf(namebuf, sizeof(namebuf), "%u", objectId);
971  objname = namebuf;
972  }
973  aclcheck_error(ACLCHECK_NOT_OWNER, objtype, objname);
974  }
975  /* Must be able to become new owner */
976  check_is_member_of_role(GetUserId(), new_ownerId);
977 
978  /* New owner must have CREATE privilege on namespace */
979  if (OidIsValid(namespaceId))
980  {
981  AclResult aclresult;
982 
983  aclresult = pg_namespace_aclcheck(namespaceId, new_ownerId,
984  ACL_CREATE);
985  if (aclresult != ACLCHECK_OK)
986  aclcheck_error(aclresult, OBJECT_SCHEMA,
987  get_namespace_name(namespaceId));
988  }
989  }
990 
991  /* Build a modified tuple */
992  nattrs = RelationGetNumberOfAttributes(rel);
993  values = palloc0(nattrs * sizeof(Datum));
994  nulls = palloc0(nattrs * sizeof(bool));
995  replaces = palloc0(nattrs * sizeof(bool));
996  values[Anum_owner - 1] = ObjectIdGetDatum(new_ownerId);
997  replaces[Anum_owner - 1] = true;
998 
999  /*
1000  * Determine the modified ACL for the new owner. This is only
1001  * necessary when the ACL is non-null.
1002  */
1003  if (Anum_acl != InvalidAttrNumber)
1004  {
1005  datum = heap_getattr(oldtup,
1006  Anum_acl, RelationGetDescr(rel), &isnull);
1007  if (!isnull)
1008  {
1009  Acl *newAcl;
1010 
1011  newAcl = aclnewowner(DatumGetAclP(datum),
1012  old_ownerId, new_ownerId);
1013  values[Anum_acl - 1] = PointerGetDatum(newAcl);
1014  replaces[Anum_acl - 1] = true;
1015  }
1016  }
1017 
1018  newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel),
1019  values, nulls, replaces);
1020 
1021  /* Perform actual update */
1022  CatalogTupleUpdate(rel, &newtup->t_self, newtup);
1023 
1024  /* Update owner dependency reference */
1025  if (classId == LargeObjectMetadataRelationId)
1026  classId = LargeObjectRelationId;
1027  changeDependencyOnOwner(classId, objectId, new_ownerId);
1028 
1029  /* Release memory */
1030  pfree(values);
1031  pfree(nulls);
1032  pfree(replaces);
1033  }
1034 
1035  InvokeObjectPostAlterHook(classId, objectId, 0);
1036 }
AttrNumber get_object_attnum_oid(Oid class_id)
AttrNumber get_object_attnum_owner(Oid class_id)
#define RelationGetDescr(relation)
Definition: rel.h:442
Oid GetUserId(void)
Definition: miscinit.c:380
#define RelationGetNumberOfAttributes(relation)
Definition: rel.h:422
#define DatumGetAclP(X)
Definition: acl.h:120
#define PointerGetDatum(X)
Definition: postgres.h:556
#define DatumGetObjectId(X)
Definition: postgres.h:500
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4908
bool superuser(void)
Definition: superuser.c:47
AttrNumber get_object_attnum_namespace(Oid class_id)
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4693
#define NAMEDATALEN
#define DatumGetName(X)
Definition: postgres.h:585
void changeDependencyOnOwner(Oid classId, Oid objectId, Oid newOwnerId)
Definition: pg_shdepend.c:310
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3353
void pfree(void *pointer)
Definition: mcxt.c:1031
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ACL_CREATE
Definition: parsenodes.h:84
ItemPointerData t_self
Definition: htup.h:65
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3094
AttrNumber get_object_attnum_acl(Oid class_id)
#define RelationGetRelationName(relation)
Definition: rel.h:450
void check_is_member_of_role(Oid member, Oid role)
Definition: acl.c:4954
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
ObjectType
Definition: parsenodes.h:1669
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:762
AttrNumber get_object_attnum_name(Oid class_id)
void * palloc0(Size size)
Definition: mcxt.c:955
AclResult
Definition: acl.h:177
HeapTuple get_catalog_object_by_oid(Relation catalog, AttrNumber oidcol, Oid objectId)
uintptr_t Datum
Definition: postgres.h:367
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:732
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:224
ObjectType get_object_type(Oid class_id, Oid object_id)
#define InvalidAttrNumber
Definition: attnum.h:23
static Datum values[MAXATTR]
Definition: bootstrap.c:167
#define elog(elevel,...)
Definition: elog.h:226
#define NameStr(name)
Definition: c.h:609
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:1113
#define snprintf
Definition: port.h:192
Acl * aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
Definition: acl.c:1052
int16 AttrNumber
Definition: attnum.h:21
#define RelationGetRelid(relation)
Definition: rel.h:416

◆ AlterObjectRename_internal()

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

Definition at line 167 of file alter.c.

References ACL_CREATE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, Assert, CatalogTupleUpdate(), CStringGetDatum, 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_freetuple(), heap_getattr, heap_modify_tuple(), HeapTupleIsValid, InvalidOid, InvokeObjectPostAlterHook, IsThereCollationInNamespace(), IsThereFunctionInNamespace(), IsThereOpClassInNamespace(), IsThereOpFamilyInNamespace(), MyDatabaseId, NameGetDatum, NameStr, namestrcpy(), OBJECT_SCHEMA, ObjectIdGetDatum, OidIsValid, palloc0(), pfree(), pg_namespace_aclcheck(), RelationGetDescr, RelationGetNumberOfAttributes, RelationGetRelationName, RelationGetRelid, ReleaseSysCache(), report_name_conflict(), report_namespace_conflict(), SearchSysCache1(), SearchSysCacheExists1, SearchSysCacheExists2, SUBSCRIPTIONNAME, superuser(), HeapTupleData::t_self, values, and WARNING.

Referenced by ExecRenameStmt().

168 {
169  Oid classId = RelationGetRelid(rel);
170  int oidCacheId = get_object_catcache_oid(classId);
171  int nameCacheId = get_object_catcache_name(classId);
172  AttrNumber Anum_name = get_object_attnum_name(classId);
173  AttrNumber Anum_namespace = get_object_attnum_namespace(classId);
174  AttrNumber Anum_owner = get_object_attnum_owner(classId);
175  ObjectType objtype = get_object_type(classId, objectId);
176  HeapTuple oldtup;
177  HeapTuple newtup;
178  Datum datum;
179  bool isnull;
180  Oid namespaceId;
181  Oid ownerId;
182  char *old_name;
183  AclResult aclresult;
184  Datum *values;
185  bool *nulls;
186  bool *replaces;
187  NameData nameattrdata;
188 
189  oldtup = SearchSysCache1(oidCacheId, ObjectIdGetDatum(objectId));
190  if (!HeapTupleIsValid(oldtup))
191  elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
192  objectId, RelationGetRelationName(rel));
193 
194  datum = heap_getattr(oldtup, Anum_name,
195  RelationGetDescr(rel), &isnull);
196  Assert(!isnull);
197  old_name = NameStr(*(DatumGetName(datum)));
198 
199  /* Get OID of namespace */
200  if (Anum_namespace > 0)
201  {
202  datum = heap_getattr(oldtup, Anum_namespace,
203  RelationGetDescr(rel), &isnull);
204  Assert(!isnull);
205  namespaceId = DatumGetObjectId(datum);
206  }
207  else
208  namespaceId = InvalidOid;
209 
210  /* Permission checks ... superusers can always do it */
211  if (!superuser())
212  {
213  /* Fail if object does not have an explicit owner */
214  if (Anum_owner <= 0)
215  ereport(ERROR,
216  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
217  (errmsg("must be superuser to rename %s",
218  getObjectDescriptionOids(classId, objectId)))));
219 
220  /* Otherwise, must be owner of the existing object */
221  datum = heap_getattr(oldtup, Anum_owner,
222  RelationGetDescr(rel), &isnull);
223  Assert(!isnull);
224  ownerId = DatumGetObjectId(datum);
225 
226  if (!has_privs_of_role(GetUserId(), DatumGetObjectId(ownerId)))
227  aclcheck_error(ACLCHECK_NOT_OWNER, objtype, old_name);
228 
229  /* User must have CREATE privilege on the namespace */
230  if (OidIsValid(namespaceId))
231  {
232  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(),
233  ACL_CREATE);
234  if (aclresult != ACLCHECK_OK)
235  aclcheck_error(aclresult, OBJECT_SCHEMA,
236  get_namespace_name(namespaceId));
237  }
238  }
239 
240  /*
241  * Check for duplicate name (more friendly than unique-index failure).
242  * Since this is just a friendliness check, we can just skip it in cases
243  * where there isn't suitable support.
244  */
245  if (classId == ProcedureRelationId)
246  {
247  Form_pg_proc proc = (Form_pg_proc) GETSTRUCT(oldtup);
248 
249  IsThereFunctionInNamespace(new_name, proc->pronargs,
250  &proc->proargtypes, proc->pronamespace);
251  }
252  else if (classId == CollationRelationId)
253  {
255 
256  IsThereCollationInNamespace(new_name, coll->collnamespace);
257  }
258  else if (classId == OperatorClassRelationId)
259  {
260  Form_pg_opclass opc = (Form_pg_opclass) GETSTRUCT(oldtup);
261 
262  IsThereOpClassInNamespace(new_name, opc->opcmethod,
263  opc->opcnamespace);
264  }
265  else if (classId == OperatorFamilyRelationId)
266  {
268 
269  IsThereOpFamilyInNamespace(new_name, opf->opfmethod,
270  opf->opfnamespace);
271  }
272  else if (classId == SubscriptionRelationId)
273  {
275  CStringGetDatum(new_name)))
276  report_name_conflict(classId, new_name);
277 
278  /* Also enforce regression testing naming rules, if enabled */
279 #ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS
280  if (strncmp(new_name, "regress_", 8) != 0)
281  elog(WARNING, "subscriptions created by regression test cases should have names starting with \"regress_\"");
282 #endif
283  }
284  else if (nameCacheId >= 0)
285  {
286  if (OidIsValid(namespaceId))
287  {
288  if (SearchSysCacheExists2(nameCacheId,
289  CStringGetDatum(new_name),
290  ObjectIdGetDatum(namespaceId)))
291  report_namespace_conflict(classId, new_name, namespaceId);
292  }
293  else
294  {
295  if (SearchSysCacheExists1(nameCacheId,
296  CStringGetDatum(new_name)))
297  report_name_conflict(classId, new_name);
298  }
299  }
300 
301  /* Build modified tuple */
302  values = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(Datum));
303  nulls = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
304  replaces = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
305  namestrcpy(&nameattrdata, new_name);
306  values[Anum_name - 1] = NameGetDatum(&nameattrdata);
307  replaces[Anum_name - 1] = true;
308  newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel),
309  values, nulls, replaces);
310 
311  /* Perform actual update */
312  CatalogTupleUpdate(rel, &oldtup->t_self, newtup);
313 
314  InvokeObjectPostAlterHook(classId, objectId, 0);
315 
316  /* Release memory */
317  pfree(values);
318  pfree(nulls);
319  pfree(replaces);
320  heap_freetuple(newtup);
321 
322  ReleaseSysCache(oldtup);
323 }
#define NameGetDatum(X)
Definition: postgres.h:595
static void report_namespace_conflict(Oid classId, const char *name, Oid nspOid)
Definition: alter.c:113
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
AttrNumber get_object_attnum_owner(Oid class_id)
#define RelationGetDescr(relation)
Definition: rel.h:442
Oid GetUserId(void)
Definition: miscinit.c:380
#define RelationGetNumberOfAttributes(relation)
Definition: rel.h:422
#define DatumGetObjectId(X)
Definition: postgres.h:500
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4908
int get_object_catcache_name(Oid class_id)
int errcode(int sqlerrcode)
Definition: elog.c:570
bool superuser(void)
Definition: superuser.c:47
AttrNumber get_object_attnum_namespace(Oid class_id)
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
unsigned int Oid
Definition: postgres_ext.h:31
int namestrcpy(Name name, const char *str)
Definition: name.c:250
#define OidIsValid(objectId)
Definition: c.h:638
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4693
void IsThereOpClassInNamespace(const char *opcname, Oid opcmethod, Oid opcnamespace)
Definition: opclasscmds.c:1706
#define DatumGetName(X)
Definition: postgres.h:585
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3353
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:183
void pfree(void *pointer)
Definition: mcxt.c:1031
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ACL_CREATE
Definition: parsenodes.h:84
int get_object_catcache_oid(Oid class_id)
ItemPointerData t_self
Definition: htup.h:65
Definition: c.h:603
char * getObjectDescriptionOids(Oid classid, Oid objid)
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3094
#define CStringGetDatum(X)
Definition: postgres.h:578
#define RelationGetRelationName(relation)
Definition: rel.h:450
void IsThereCollationInNamespace(const char *collname, Oid nspOid)
#define ereport(elevel, rest)
Definition: elog.h:141
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
ObjectType
Definition: parsenodes.h:1669
#define WARNING
Definition: elog.h:40
void IsThereFunctionInNamespace(const char *proname, int pronargs, oidvector *proargtypes, Oid nspOid)
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:762
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
FormData_pg_opfamily * Form_pg_opfamily
Definition: pg_opfamily.h:51
AttrNumber get_object_attnum_name(Oid class_id)
void * palloc0(Size size)
Definition: mcxt.c:955
AclResult
Definition: acl.h:177
uintptr_t Datum
Definition: postgres.h:367
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
Oid MyDatabaseId
Definition: globals.c:85
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:134
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Assert(condition)
Definition: c.h:732
static void report_name_conflict(Oid classId, const char *name)
Definition: alter.c:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:224
ObjectType get_object_type(Oid class_id, Oid object_id)
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:185
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:51
static Datum values[MAXATTR]
Definition: bootstrap.c:167
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
#define NameStr(name)
Definition: c.h:609
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:1113
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:83
int16 AttrNumber
Definition: attnum.h:21
#define RelationGetRelid(relation)
Definition: rel.h:416
void IsThereOpFamilyInNamespace(const char *opfname, Oid opfmethod, Oid opfnamespace)
Definition: opclasscmds.c:1729

◆ ExecAlterObjectDependsStmt()

ObjectAddress ExecAlterObjectDependsStmt ( AlterObjectDependsStmt stmt,
ObjectAddress refAddress 
)

Definition at line 432 of file alter.c.

References AccessExclusiveLock, Assert, DEPENDENCY_AUTO_EXTENSION, AlterObjectDependsStmt::extname, get_object_address(), get_object_address_rv(), NoLock, AlterObjectDependsStmt::object, OBJECT_EXTENSION, AlterObjectDependsStmt::objectType, recordDependencyOn(), AlterObjectDependsStmt::relation, and table_close().

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

433 {
434  ObjectAddress address;
435  ObjectAddress refAddr;
436  Relation rel;
437 
438  address =
439  get_object_address_rv(stmt->objectType, stmt->relation, (List *) stmt->object,
440  &rel, AccessExclusiveLock, false);
441 
442  /*
443  * If a relation was involved, it would have been opened and locked. We
444  * don't need the relation here, but we'll retain the lock until commit.
445  */
446  if (rel)
447  table_close(rel, NoLock);
448 
449  refAddr = get_object_address(OBJECT_EXTENSION, (Node *) stmt->extname,
450  &rel, AccessExclusiveLock, false);
451  Assert(rel == NULL);
452  if (refAddress)
453  *refAddress = refAddr;
454 
455  recordDependencyOn(&address, &refAddr, DEPENDENCY_AUTO_EXTENSION);
456 
457  return address;
458 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
Definition: nodes.h:524
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:43
#define NoLock
Definition: lockdefs.h:34
ObjectAddress get_object_address_rv(ObjectType objtype, RangeVar *rel, List *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
#define Assert(condition)
Definition: c.h:732
ObjectAddress get_object_address(ObjectType objtype, Node *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
#define AccessExclusiveLock
Definition: lockdefs.h:45
Definition: pg_list.h:50

◆ ExecAlterObjectSchemaStmt()

ObjectAddress ExecAlterObjectSchemaStmt ( AlterObjectSchemaStmt stmt,
ObjectAddress oldSchemaAddr 
)

Definition at line 470 of file alter.c.

References AccessExclusiveLock, AlterExtensionNamespace(), AlterObjectNamespace_internal(), AlterTableNamespace(), AlterTypeNamespace(), Assert, castNode, ObjectAddress::classId, elog, ERROR, get_object_address(), InvalidObjectAddress, LookupCreationNamespace(), AlterObjectSchemaStmt::newschema, AlterObjectSchemaStmt::object, 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, AlterObjectSchemaStmt::objectType, RowExclusiveLock, strVal, table_close(), and table_open().

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

472 {
473  ObjectAddress address;
474  Oid oldNspOid;
475 
476  switch (stmt->objectType)
477  {
478  case OBJECT_EXTENSION:
479  address = AlterExtensionNamespace(strVal((Value *) stmt->object), stmt->newschema,
480  oldSchemaAddr ? &oldNspOid : NULL);
481  break;
482 
484  case OBJECT_SEQUENCE:
485  case OBJECT_TABLE:
486  case OBJECT_VIEW:
487  case OBJECT_MATVIEW:
488  address = AlterTableNamespace(stmt,
489  oldSchemaAddr ? &oldNspOid : NULL);
490  break;
491 
492  case OBJECT_DOMAIN:
493  case OBJECT_TYPE:
494  address = AlterTypeNamespace(castNode(List, stmt->object), stmt->newschema,
495  stmt->objectType,
496  oldSchemaAddr ? &oldNspOid : NULL);
497  break;
498 
499  /* generic code path */
500  case OBJECT_AGGREGATE:
501  case OBJECT_COLLATION:
502  case OBJECT_CONVERSION:
503  case OBJECT_FUNCTION:
504  case OBJECT_OPERATOR:
505  case OBJECT_OPCLASS:
506  case OBJECT_OPFAMILY:
507  case OBJECT_PROCEDURE:
508  case OBJECT_ROUTINE:
511  case OBJECT_TSDICTIONARY:
512  case OBJECT_TSPARSER:
513  case OBJECT_TSTEMPLATE:
514  {
515  Relation catalog;
516  Relation relation;
517  Oid classId;
518  Oid nspOid;
519 
520  address = get_object_address(stmt->objectType,
521  stmt->object,
522  &relation,
524  false);
525  Assert(relation == NULL);
526  classId = address.classId;
527  catalog = table_open(classId, RowExclusiveLock);
528  nspOid = LookupCreationNamespace(stmt->newschema);
529 
530  oldNspOid = AlterObjectNamespace_internal(catalog, address.objectId,
531  nspOid);
532  table_close(catalog, RowExclusiveLock);
533  }
534  break;
535 
536  default:
537  elog(ERROR, "unrecognized AlterObjectSchemaStmt type: %d",
538  (int) stmt->objectType);
539  return InvalidObjectAddress; /* keep compiler happy */
540  }
541 
542  if (oldSchemaAddr)
543  ObjectAddressSet(*oldSchemaAddr, NamespaceRelationId, oldNspOid);
544 
545  return address;
546 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define castNode(_type_, nodeptr)
Definition: nodes.h:593
Oid LookupCreationNamespace(const char *nspname)
Definition: namespace.c:2928
ObjectAddress AlterTypeNamespace(List *names, const char *newschema, ObjectType objecttype, Oid *oldschema)
Definition: typecmds.c:3504
#define strVal(v)
Definition: value.h:54
static Oid AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
Definition: alter.c:665
unsigned int Oid
Definition: postgres_ext.h:31
ObjectAddress AlterTableNamespace(AlterObjectSchemaStmt *stmt, Oid *oldschema)
Definition: tablecmds.c:14183
#define ERROR
Definition: elog.h:43
#define RowExclusiveLock
Definition: lockdefs.h:38
#define Assert(condition)
Definition: c.h:732
Definition: value.h:42
ObjectAddress get_object_address(ObjectType objtype, Node *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define AccessExclusiveLock
Definition: lockdefs.h:45
const ObjectAddress InvalidObjectAddress
#define elog(elevel,...)
Definition: elog.h:226
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
Definition: pg_list.h:50
ObjectAddress AlterExtensionNamespace(const char *extensionName, const char *newschema, Oid *oldschema)
Definition: extension.c:2708

◆ ExecAlterOwnerStmt()

ObjectAddress ExecAlterOwnerStmt ( AlterOwnerStmt stmt)

Definition at line 809 of file alter.c.

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, AlterOwnerStmt::newowner, AlterOwnerStmt::object, 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, AlterOwnerStmt::objectType, RowExclusiveLock, strVal, table_close(), and table_open().

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

810 {
811  Oid newowner = get_rolespec_oid(stmt->newowner, false);
812 
813  switch (stmt->objectType)
814  {
815  case OBJECT_DATABASE:
816  return AlterDatabaseOwner(strVal((Value *) stmt->object), newowner);
817 
818  case OBJECT_SCHEMA:
819  return AlterSchemaOwner(strVal((Value *) stmt->object), newowner);
820 
821  case OBJECT_TYPE:
822  case OBJECT_DOMAIN: /* same as TYPE */
823  return AlterTypeOwner(castNode(List, stmt->object), newowner, stmt->objectType);
824  break;
825 
826  case OBJECT_FDW:
828  newowner);
829 
831  return AlterForeignServerOwner(strVal((Value *) stmt->object),
832  newowner);
833 
835  return AlterEventTriggerOwner(strVal((Value *) stmt->object),
836  newowner);
837 
838  case OBJECT_PUBLICATION:
839  return AlterPublicationOwner(strVal((Value *) stmt->object),
840  newowner);
841 
842  case OBJECT_SUBSCRIPTION:
843  return AlterSubscriptionOwner(strVal((Value *) stmt->object),
844  newowner);
845 
846  /* Generic cases */
847  case OBJECT_AGGREGATE:
848  case OBJECT_COLLATION:
849  case OBJECT_CONVERSION:
850  case OBJECT_FUNCTION:
851  case OBJECT_LANGUAGE:
852  case OBJECT_LARGEOBJECT:
853  case OBJECT_OPERATOR:
854  case OBJECT_OPCLASS:
855  case OBJECT_OPFAMILY:
856  case OBJECT_PROCEDURE:
857  case OBJECT_ROUTINE:
859  case OBJECT_TABLESPACE:
860  case OBJECT_TSDICTIONARY:
862  {
863  Relation catalog;
864  Relation relation;
865  Oid classId;
866  ObjectAddress address;
867 
868  address = get_object_address(stmt->objectType,
869  stmt->object,
870  &relation,
872  false);
873  Assert(relation == NULL);
874  classId = address.classId;
875 
876  /*
877  * XXX - get_object_address returns Oid of pg_largeobject
878  * catalog for OBJECT_LARGEOBJECT because of historical
879  * reasons. Fix up it here.
880  */
881  if (classId == LargeObjectRelationId)
882  classId = LargeObjectMetadataRelationId;
883 
884  catalog = table_open(classId, RowExclusiveLock);
885 
886  AlterObjectOwner_internal(catalog, address.objectId, newowner);
887  table_close(catalog, RowExclusiveLock);
888 
889  return address;
890  }
891  break;
892 
893  default:
894  elog(ERROR, "unrecognized AlterOwnerStmt type: %d",
895  (int) stmt->objectType);
896  return InvalidObjectAddress; /* keep compiler happy */
897  }
898 }
RoleSpec * newowner
Definition: parsenodes.h:2927
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define castNode(_type_, nodeptr)
Definition: nodes.h:593
ObjectType objectType
Definition: parsenodes.h:2924
#define strVal(v)
Definition: value.h:54
unsigned int Oid
Definition: postgres_ext.h:31
ObjectAddress AlterEventTriggerOwner(const char *name, Oid newOwnerId)
ObjectAddress AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype)
Definition: typecmds.c:3300
#define ERROR
Definition: elog.h:43
ObjectAddress AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
Definition: foreigncmds.c:275
void AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId)
Definition: alter.c:910
#define RowExclusiveLock
Definition: lockdefs.h:38
ObjectAddress AlterSubscriptionOwner(const char *name, Oid newOwnerId)
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5225
ObjectAddress AlterPublicationOwner(const char *name, Oid newOwnerId)
ObjectAddress AlterSchemaOwner(const char *name, Oid newOwnerId)
Definition: schemacmds.c:323
#define Assert(condition)
Definition: c.h:732
Definition: value.h:42
ObjectAddress AlterForeignServerOwner(const char *name, Oid newOwnerId)
Definition: foreigncmds.c:415
ObjectAddress get_object_address(ObjectType objtype, Node *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
ObjectAddress AlterDatabaseOwner(const char *dbname, Oid newOwnerId)
Definition: dbcommands.c:1643
#define AccessExclusiveLock
Definition: lockdefs.h:45
const ObjectAddress InvalidObjectAddress
#define elog(elevel,...)
Definition: elog.h:226
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
Definition: pg_list.h:50

◆ ExecRenameStmt()

ObjectAddress ExecRenameStmt ( RenameStmt stmt)

Definition at line 332 of file alter.c.

References AccessExclusiveLock, AlterObjectRename_internal(), Assert, ObjectAddress::classId, elog, ERROR, get_object_address(), InvalidObjectAddress, RenameStmt::newname, RenameStmt::object, 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, RenameStmt::relation, rename_policy(), renameatt(), RenameConstraint(), RenameDatabase(), RenameRelation(), RenameRewriteRule(), RenameRole(), RenameSchema(), RenameTableSpace(), renametrig(), RenameStmt::renameType, RenameType(), RowExclusiveLock, RenameStmt::subname, table_close(), and table_open().

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

333 {
334  switch (stmt->renameType)
335  {
338  return RenameConstraint(stmt);
339 
340  case OBJECT_DATABASE:
341  return RenameDatabase(stmt->subname, stmt->newname);
342 
343  case OBJECT_ROLE:
344  return RenameRole(stmt->subname, stmt->newname);
345 
346  case OBJECT_SCHEMA:
347  return RenameSchema(stmt->subname, stmt->newname);
348 
349  case OBJECT_TABLESPACE:
350  return RenameTableSpace(stmt->subname, stmt->newname);
351 
352  case OBJECT_TABLE:
353  case OBJECT_SEQUENCE:
354  case OBJECT_VIEW:
355  case OBJECT_MATVIEW:
356  case OBJECT_INDEX:
358  return RenameRelation(stmt);
359 
360  case OBJECT_COLUMN:
361  case OBJECT_ATTRIBUTE:
362  return renameatt(stmt);
363 
364  case OBJECT_RULE:
365  return RenameRewriteRule(stmt->relation, stmt->subname,
366  stmt->newname);
367 
368  case OBJECT_TRIGGER:
369  return renametrig(stmt);
370 
371  case OBJECT_POLICY:
372  return rename_policy(stmt);
373 
374  case OBJECT_DOMAIN:
375  case OBJECT_TYPE:
376  return RenameType(stmt);
377 
378  case OBJECT_AGGREGATE:
379  case OBJECT_COLLATION:
380  case OBJECT_CONVERSION:
382  case OBJECT_FDW:
384  case OBJECT_FUNCTION:
385  case OBJECT_OPCLASS:
386  case OBJECT_OPFAMILY:
387  case OBJECT_LANGUAGE:
388  case OBJECT_PROCEDURE:
389  case OBJECT_ROUTINE:
392  case OBJECT_TSDICTIONARY:
393  case OBJECT_TSPARSER:
394  case OBJECT_TSTEMPLATE:
395  case OBJECT_PUBLICATION:
396  case OBJECT_SUBSCRIPTION:
397  {
398  ObjectAddress address;
399  Relation catalog;
400  Relation relation;
401 
402  address = get_object_address(stmt->renameType,
403  stmt->object,
404  &relation,
405  AccessExclusiveLock, false);
406  Assert(relation == NULL);
407 
408  catalog = table_open(address.classId, RowExclusiveLock);
410  address.objectId,
411  stmt->newname);
412  table_close(catalog, RowExclusiveLock);
413 
414  return address;
415  }
416 
417  default:
418  elog(ERROR, "unrecognized rename stmt type: %d",
419  (int) stmt->renameType);
420  return InvalidObjectAddress; /* keep compiler happy */
421  }
422 }
ObjectAddress RenameSchema(const char *oldname, const char *newname)
Definition: schemacmds.c:242
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
ObjectAddress RenameType(RenameStmt *stmt)
Definition: typecmds.c:3222
char * subname
Definition: parsenodes.h:2883
ObjectType renameType
Definition: parsenodes.h:2879
ObjectAddress RenameRelation(RenameStmt *stmt)
Definition: tablecmds.c:3274
char * newname
Definition: parsenodes.h:2885
ObjectAddress RenameDatabase(const char *oldname, const char *newname)
Definition: dbcommands.c:1010
#define ERROR
Definition: elog.h:43
ObjectAddress rename_policy(RenameStmt *stmt)
Definition: policy.c:1218
#define RowExclusiveLock
Definition: lockdefs.h:38
Node * object
Definition: parsenodes.h:2882
ObjectAddress renametrig(RenameStmt *stmt)
Definition: trigger.c:1673
ObjectAddress renameatt(RenameStmt *stmt)
Definition: tablecmds.c:3079
ObjectAddress RenameConstraint(RenameStmt *stmt)
Definition: tablecmds.c:3223
RangeVar * relation
Definition: parsenodes.h:2881
ObjectAddress RenameRole(const char *oldname, const char *newname)
Definition: user.c:1161
#define Assert(condition)
Definition: c.h:732
ObjectAddress get_object_address(ObjectType objtype, Node *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
static void AlterObjectRename_internal(Relation rel, Oid objectId, const char *new_name)
Definition: alter.c:167
ObjectAddress RenameRewriteRule(RangeVar *relation, const char *oldName, const char *newName)
ObjectAddress RenameTableSpace(const char *oldname, const char *newname)
Definition: tablespace.c:926
#define AccessExclusiveLock
Definition: lockdefs.h:45
const ObjectAddress InvalidObjectAddress
#define elog(elevel,...)
Definition: elog.h:226
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ report_name_conflict()

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

Definition at line 78 of file alter.c.

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

Referenced by AlterObjectRename_internal().

79 {
80  char *msgfmt;
81 
82  switch (classId)
83  {
84  case EventTriggerRelationId:
85  msgfmt = gettext_noop("event trigger \"%s\" already exists");
86  break;
87  case ForeignDataWrapperRelationId:
88  msgfmt = gettext_noop("foreign-data wrapper \"%s\" already exists");
89  break;
90  case ForeignServerRelationId:
91  msgfmt = gettext_noop("server \"%s\" already exists");
92  break;
93  case LanguageRelationId:
94  msgfmt = gettext_noop("language \"%s\" already exists");
95  break;
96  case PublicationRelationId:
97  msgfmt = gettext_noop("publication \"%s\" already exists");
98  break;
99  case SubscriptionRelationId:
100  msgfmt = gettext_noop("subscription \"%s\" already exists");
101  break;
102  default:
103  elog(ERROR, "unsupported object class %u", classId);
104  break;
105  }
106 
107  ereport(ERROR,
109  errmsg(msgfmt, name)));
110 }
#define gettext_noop(x)
Definition: c.h:1117
int errcode(int sqlerrcode)
Definition: elog.c:570
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:33

◆ report_namespace_conflict()

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

Definition at line 113 of file alter.c.

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

Referenced by AlterObjectNamespace_internal(), and AlterObjectRename_internal().

114 {
115  char *msgfmt;
116 
117  Assert(OidIsValid(nspOid));
118 
119  switch (classId)
120  {
121  case ConversionRelationId:
122  Assert(OidIsValid(nspOid));
123  msgfmt = gettext_noop("conversion \"%s\" already exists in schema \"%s\"");
124  break;
125  case StatisticExtRelationId:
126  Assert(OidIsValid(nspOid));
127  msgfmt = gettext_noop("statistics object \"%s\" already exists in schema \"%s\"");
128  break;
129  case TSParserRelationId:
130  Assert(OidIsValid(nspOid));
131  msgfmt = gettext_noop("text search parser \"%s\" already exists in schema \"%s\"");
132  break;
133  case TSDictionaryRelationId:
134  Assert(OidIsValid(nspOid));
135  msgfmt = gettext_noop("text search dictionary \"%s\" already exists in schema \"%s\"");
136  break;
137  case TSTemplateRelationId:
138  Assert(OidIsValid(nspOid));
139  msgfmt = gettext_noop("text search template \"%s\" already exists in schema \"%s\"");
140  break;
141  case TSConfigRelationId:
142  Assert(OidIsValid(nspOid));
143  msgfmt = gettext_noop("text search configuration \"%s\" already exists in schema \"%s\"");
144  break;
145  default:
146  elog(ERROR, "unsupported object class %u", classId);
147  break;
148  }
149 
150  ereport(ERROR,
152  errmsg(msgfmt, name, get_namespace_name(nspOid))));
153 }
#define gettext_noop(x)
Definition: c.h:1117
int errcode(int sqlerrcode)
Definition: elog.c:570
#define OidIsValid(objectId)
Definition: c.h:638
#define ERROR
Definition: elog.h:43
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3094
#define ereport(elevel, rest)
Definition: elog.h:141
#define Assert(condition)
Definition: c.h:732
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:33