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_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_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/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 "miscadmin.h"
#include "parser/parse_func.h"
#include "replication/logicalworker.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 722 of file alter.c.

723 {
724  Oid classId = RelationGetRelid(rel);
725  int oidCacheId = get_object_catcache_oid(classId);
726  int nameCacheId = get_object_catcache_name(classId);
727  AttrNumber Anum_name = get_object_attnum_name(classId);
728  AttrNumber Anum_namespace = get_object_attnum_namespace(classId);
729  AttrNumber Anum_owner = get_object_attnum_owner(classId);
730  Oid oldNspOid;
731  Datum name,
732  namespace;
733  bool isnull;
734  HeapTuple tup,
735  newtup;
736  Datum *values;
737  bool *nulls;
738  bool *replaces;
739 
740  tup = SearchSysCacheCopy1(oidCacheId, ObjectIdGetDatum(objid));
741  if (!HeapTupleIsValid(tup)) /* should not happen */
742  elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
743  objid, RelationGetRelationName(rel));
744 
745  name = heap_getattr(tup, Anum_name, RelationGetDescr(rel), &isnull);
746  Assert(!isnull);
747  namespace = heap_getattr(tup, Anum_namespace, RelationGetDescr(rel),
748  &isnull);
749  Assert(!isnull);
750  oldNspOid = DatumGetObjectId(namespace);
751 
752  /*
753  * If the object is already in the correct namespace, we don't need to do
754  * anything except fire the object access hook.
755  */
756  if (oldNspOid == nspOid)
757  {
758  InvokeObjectPostAlterHook(classId, objid, 0);
759  return oldNspOid;
760  }
761 
762  /* Check basic namespace related issues */
763  CheckSetNamespace(oldNspOid, nspOid);
764 
765  /* Permission checks ... superusers can always do it */
766  if (!superuser())
767  {
768  Datum owner;
769  Oid ownerId;
770  AclResult aclresult;
771 
772  /* Fail if object does not have an explicit owner */
773  if (Anum_owner <= 0)
774  ereport(ERROR,
775  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
776  errmsg("must be superuser to set schema of %s",
777  getObjectDescriptionOids(classId, objid))));
778 
779  /* Otherwise, must be owner of the existing object */
780  owner = heap_getattr(tup, Anum_owner, RelationGetDescr(rel), &isnull);
781  Assert(!isnull);
782  ownerId = DatumGetObjectId(owner);
783 
784  if (!has_privs_of_role(GetUserId(), ownerId))
786  NameStr(*(DatumGetName(name))));
787 
788  /* User must have CREATE privilege on new namespace */
789  aclresult = object_aclcheck(NamespaceRelationId, nspOid, GetUserId(), ACL_CREATE);
790  if (aclresult != ACLCHECK_OK)
791  aclcheck_error(aclresult, OBJECT_SCHEMA,
792  get_namespace_name(nspOid));
793  }
794 
795  /*
796  * Check for duplicate name (more friendly than unique-index failure).
797  * Since this is just a friendliness check, we can just skip it in cases
798  * where there isn't suitable support.
799  */
800  if (classId == ProcedureRelationId)
801  {
802  Form_pg_proc proc = (Form_pg_proc) GETSTRUCT(tup);
803 
804  IsThereFunctionInNamespace(NameStr(proc->proname), proc->pronargs,
805  &proc->proargtypes, nspOid);
806  }
807  else if (classId == CollationRelationId)
808  {
810 
811  IsThereCollationInNamespace(NameStr(coll->collname), nspOid);
812  }
813  else if (classId == OperatorClassRelationId)
814  {
816 
817  IsThereOpClassInNamespace(NameStr(opc->opcname),
818  opc->opcmethod, nspOid);
819  }
820  else if (classId == OperatorFamilyRelationId)
821  {
823 
824  IsThereOpFamilyInNamespace(NameStr(opf->opfname),
825  opf->opfmethod, nspOid);
826  }
827  else if (nameCacheId >= 0 &&
828  SearchSysCacheExists2(nameCacheId, name,
829  ObjectIdGetDatum(nspOid)))
832  nspOid);
833 
834  /* Build modified tuple */
836  nulls = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
837  replaces = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
838  values[Anum_namespace - 1] = ObjectIdGetDatum(nspOid);
839  replaces[Anum_namespace - 1] = true;
840  newtup = heap_modify_tuple(tup, RelationGetDescr(rel),
841  values, nulls, replaces);
842 
843  /* Perform actual update */
844  CatalogTupleUpdate(rel, &tup->t_self, newtup);
845 
846  /* Release memory */
847  pfree(values);
848  pfree(nulls);
849  pfree(replaces);
850 
851  /* update dependency to point to the new schema */
852  if (changeDependencyFor(classId, objid,
853  NamespaceRelationId, oldNspOid, nspOid) != 1)
854  elog(ERROR, "could not change schema dependency for object %u",
855  objid);
856 
857  InvokeObjectPostAlterHook(classId, objid, 0);
858 
859  return oldNspOid;
860 }
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4961
AclResult
Definition: acl.h:181
@ ACLCHECK_OK
Definition: acl.h:182
@ ACLCHECK_NOT_OWNER
Definition: acl.h:184
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2669
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition: aclchk.c:3760
static void report_namespace_conflict(Oid classId, const char *name, Oid nspOid)
Definition: alter.c:114
int16 AttrNumber
Definition: attnum.h:21
static Datum values[MAXATTR]
Definition: bootstrap.c:156
#define NameStr(name)
Definition: c.h:735
void IsThereCollationInNamespace(const char *collname, Oid nspOid)
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define ERROR
Definition: elog.h:39
#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, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:1201
#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
Assert(fmt[strlen(fmt) - 1] !='\n')
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3348
void pfree(void *pointer)
Definition: mcxt.c:1456
void * palloc0(Size size)
Definition: mcxt.c:1257
Oid GetUserId(void)
Definition: miscinit.c:509
void CheckSetNamespace(Oid oldNspOid, Oid nspOid)
Definition: namespace.c:2992
#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:1731
void IsThereOpClassInNamespace(const char *opcname, Oid opcmethod, Oid opcnamespace)
Definition: opclasscmds.c:1708
@ OBJECT_SCHEMA
Definition: parsenodes.h:2156
#define ACL_CREATE
Definition: parsenodes.h:92
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:504
#define RelationGetDescr(relation)
Definition: rel.h:530
#define RelationGetNumberOfAttributes(relation)
Definition: rel.h:510
#define RelationGetRelationName(relation)
Definition: rel.h:538
ItemPointerData t_self
Definition: htup.h:65
bool superuser(void)
Definition: superuser.c:46
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:182
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:193
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 618 of file alter.c.

620 {
621  Oid oldNspOid = InvalidOid;
622  ObjectAddress dep;
623 
624  dep.classId = classId;
625  dep.objectId = objid;
626  dep.objectSubId = 0;
627 
628  switch (getObjectClass(&dep))
629  {
630  case OCLASS_CLASS:
631  {
632  Relation rel;
633 
634  rel = relation_open(objid, AccessExclusiveLock);
635  oldNspOid = RelationGetNamespace(rel);
636 
637  AlterTableNamespaceInternal(rel, oldNspOid, nspOid, objsMoved);
638 
639  relation_close(rel, NoLock);
640  break;
641  }
642 
643  case OCLASS_TYPE:
644  oldNspOid = AlterTypeNamespace_oid(objid, nspOid, objsMoved);
645  break;
646 
647  case OCLASS_PROC:
648  case OCLASS_COLLATION:
649  case OCLASS_CONVERSION:
650  case OCLASS_OPERATOR:
651  case OCLASS_OPCLASS:
652  case OCLASS_OPFAMILY:
654  case OCLASS_TSPARSER:
655  case OCLASS_TSDICT:
656  case OCLASS_TSTEMPLATE:
657  case OCLASS_TSCONFIG:
658  {
659  Relation catalog;
660 
661  catalog = table_open(classId, RowExclusiveLock);
662 
663  oldNspOid = AlterObjectNamespace_internal(catalog, objid,
664  nspOid);
665 
666  table_close(catalog, RowExclusiveLock);
667  }
668  break;
669 
670  case OCLASS_CAST:
671  case OCLASS_CONSTRAINT:
672  case OCLASS_DEFAULT:
673  case OCLASS_LANGUAGE:
674  case OCLASS_LARGEOBJECT:
675  case OCLASS_AM:
676  case OCLASS_AMOP:
677  case OCLASS_AMPROC:
678  case OCLASS_REWRITE:
679  case OCLASS_TRIGGER:
680  case OCLASS_SCHEMA:
681  case OCLASS_ROLE:
683  case OCLASS_DATABASE:
684  case OCLASS_TBLSPACE:
685  case OCLASS_FDW:
687  case OCLASS_USER_MAPPING:
688  case OCLASS_DEFACL:
689  case OCLASS_EXTENSION:
692  case OCLASS_POLICY:
693  case OCLASS_PUBLICATION:
696  case OCLASS_SUBSCRIPTION:
697  case OCLASS_TRANSFORM:
698  /* ignore object types that don't have schema-qualified names */
699  break;
700 
701  /*
702  * There's intentionally no default: case here; we want the
703  * compiler to warn if a new OCLASS hasn't been handled above.
704  */
705  }
706 
707  return oldNspOid;
708 }
static Oid AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
Definition: alter.c:722
ObjectClass getObjectClass(const ObjectAddress *object)
Definition: dependency.c:2836
@ OCLASS_OPERATOR
Definition: dependency.h:100
@ OCLASS_PARAMETER_ACL
Definition: dependency.h:124
@ OCLASS_LARGEOBJECT
Definition: dependency.h:99
@ OCLASS_FDW
Definition: dependency.h:118
@ OCLASS_OPFAMILY
Definition: dependency.h:102
@ OCLASS_DEFACL
Definition: dependency.h:121
@ OCLASS_TSPARSER
Definition: dependency.h:110
@ OCLASS_TRIGGER
Definition: dependency.h:107
@ OCLASS_DEFAULT
Definition: dependency.h:97
@ OCLASS_TSTEMPLATE
Definition: dependency.h:112
@ OCLASS_AMPROC
Definition: dependency.h:105
@ OCLASS_TBLSPACE
Definition: dependency.h:117
@ OCLASS_TSCONFIG
Definition: dependency.h:113
@ OCLASS_TYPE
Definition: dependency.h:92
@ OCLASS_LANGUAGE
Definition: dependency.h:98
@ OCLASS_CAST
Definition: dependency.h:93
@ OCLASS_SUBSCRIPTION
Definition: dependency.h:129
@ OCLASS_PUBLICATION_NAMESPACE
Definition: dependency.h:127
@ OCLASS_EXTENSION
Definition: dependency.h:122
@ OCLASS_COLLATION
Definition: dependency.h:94
@ OCLASS_FOREIGN_SERVER
Definition: dependency.h:119
@ OCLASS_REWRITE
Definition: dependency.h:106
@ OCLASS_STATISTIC_EXT
Definition: dependency.h:109
@ OCLASS_PROC
Definition: dependency.h:91
@ OCLASS_OPCLASS
Definition: dependency.h:101
@ OCLASS_CONVERSION
Definition: dependency.h:96
@ OCLASS_DATABASE
Definition: dependency.h:116
@ OCLASS_ROLE_MEMBERSHIP
Definition: dependency.h:115
@ OCLASS_SCHEMA
Definition: dependency.h:108
@ OCLASS_EVENT_TRIGGER
Definition: dependency.h:123
@ OCLASS_CLASS
Definition: dependency.h:90
@ OCLASS_TRANSFORM
Definition: dependency.h:130
@ OCLASS_ROLE
Definition: dependency.h:114
@ OCLASS_CONSTRAINT
Definition: dependency.h:95
@ OCLASS_POLICY
Definition: dependency.h:125
@ OCLASS_USER_MAPPING
Definition: dependency.h:120
@ OCLASS_PUBLICATION_REL
Definition: dependency.h:128
@ OCLASS_AM
Definition: dependency.h:103
@ OCLASS_TSDICT
Definition: dependency.h:111
@ OCLASS_PUBLICATION
Definition: dependency.h:126
@ OCLASS_AMOP
Definition: dependency.h:104
#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:545
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: relation.c:206
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: relation.c:48
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:17235
Oid AlterTypeNamespace_oid(Oid typeOid, Oid nspOid, ObjectAddresses *objsMoved)
Definition: typecmds.c:3908

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_PARAMETER_ACL, OCLASS_POLICY, OCLASS_PROC, OCLASS_PUBLICATION, OCLASS_PUBLICATION_NAMESPACE, OCLASS_PUBLICATION_REL, OCLASS_REWRITE, OCLASS_ROLE, OCLASS_ROLE_MEMBERSHIP, 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().

◆ AlterObjectOwner_internal()

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

Definition at line 968 of file alter.c.

969 {
970  Oid classId = RelationGetRelid(rel);
971  AttrNumber Anum_oid = get_object_attnum_oid(classId);
972  AttrNumber Anum_owner = get_object_attnum_owner(classId);
973  AttrNumber Anum_namespace = get_object_attnum_namespace(classId);
974  AttrNumber Anum_acl = get_object_attnum_acl(classId);
975  AttrNumber Anum_name = get_object_attnum_name(classId);
976  HeapTuple oldtup;
977  Datum datum;
978  bool isnull;
979  Oid old_ownerId;
980  Oid namespaceId = InvalidOid;
981 
982  oldtup = get_catalog_object_by_oid(rel, Anum_oid, objectId);
983  if (oldtup == NULL)
984  elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
985  objectId, RelationGetRelationName(rel));
986 
987  datum = heap_getattr(oldtup, Anum_owner,
988  RelationGetDescr(rel), &isnull);
989  Assert(!isnull);
990  old_ownerId = DatumGetObjectId(datum);
991 
992  if (Anum_namespace != InvalidAttrNumber)
993  {
994  datum = heap_getattr(oldtup, Anum_namespace,
995  RelationGetDescr(rel), &isnull);
996  Assert(!isnull);
997  namespaceId = DatumGetObjectId(datum);
998  }
999 
1000  if (old_ownerId != new_ownerId)
1001  {
1002  AttrNumber nattrs;
1003  HeapTuple newtup;
1004  Datum *values;
1005  bool *nulls;
1006  bool *replaces;
1007 
1008  /* Superusers can bypass permission checks */
1009  if (!superuser())
1010  {
1011  /* must be owner */
1012  if (!has_privs_of_role(GetUserId(), old_ownerId))
1013  {
1014  char *objname;
1015  char namebuf[NAMEDATALEN];
1016 
1017  if (Anum_name != InvalidAttrNumber)
1018  {
1019  datum = heap_getattr(oldtup, Anum_name,
1020  RelationGetDescr(rel), &isnull);
1021  Assert(!isnull);
1022  objname = NameStr(*DatumGetName(datum));
1023  }
1024  else
1025  {
1026  snprintf(namebuf, sizeof(namebuf), "%u", objectId);
1027  objname = namebuf;
1028  }
1030  objname);
1031  }
1032  /* Must be able to become new owner */
1033  check_can_set_role(GetUserId(), new_ownerId);
1034 
1035  /* New owner must have CREATE privilege on namespace */
1036  if (OidIsValid(namespaceId))
1037  {
1038  AclResult aclresult;
1039 
1040  aclresult = object_aclcheck(NamespaceRelationId, namespaceId, new_ownerId,
1041  ACL_CREATE);
1042  if (aclresult != ACLCHECK_OK)
1043  aclcheck_error(aclresult, OBJECT_SCHEMA,
1044  get_namespace_name(namespaceId));
1045  }
1046  }
1047 
1048  /* Build a modified tuple */
1049  nattrs = RelationGetNumberOfAttributes(rel);
1050  values = palloc0(nattrs * sizeof(Datum));
1051  nulls = palloc0(nattrs * sizeof(bool));
1052  replaces = palloc0(nattrs * sizeof(bool));
1053  values[Anum_owner - 1] = ObjectIdGetDatum(new_ownerId);
1054  replaces[Anum_owner - 1] = true;
1055 
1056  /*
1057  * Determine the modified ACL for the new owner. This is only
1058  * necessary when the ACL is non-null.
1059  */
1060  if (Anum_acl != InvalidAttrNumber)
1061  {
1062  datum = heap_getattr(oldtup,
1063  Anum_acl, RelationGetDescr(rel), &isnull);
1064  if (!isnull)
1065  {
1066  Acl *newAcl;
1067 
1068  newAcl = aclnewowner(DatumGetAclP(datum),
1069  old_ownerId, new_ownerId);
1070  values[Anum_acl - 1] = PointerGetDatum(newAcl);
1071  replaces[Anum_acl - 1] = true;
1072  }
1073  }
1074 
1075  newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel),
1076  values, nulls, replaces);
1077 
1078  /* Perform actual update */
1079  CatalogTupleUpdate(rel, &newtup->t_self, newtup);
1080 
1081  /* Update owner dependency reference */
1082  if (classId == LargeObjectMetadataRelationId)
1083  classId = LargeObjectRelationId;
1084  changeDependencyOnOwner(classId, objectId, new_ownerId);
1085 
1086  /* Release memory */
1087  pfree(values);
1088  pfree(nulls);
1089  pfree(replaces);
1090  }
1091 
1092  InvokeObjectPostAlterHook(classId, objectId, 0);
1093 }
Acl * aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
Definition: acl.c:1087
void check_can_set_role(Oid member, Oid role)
Definition: acl.c:5018
#define DatumGetAclP(X)
Definition: acl.h:120
#define InvalidAttrNumber
Definition: attnum.h:23
#define OidIsValid(objectId)
Definition: c.h:764
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:313
#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, RelationGetRelid, snprintf, superuser(), HeapTupleData::t_self, 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 168 of file alter.c.

169 {
170  Oid classId = RelationGetRelid(rel);
171  int oidCacheId = get_object_catcache_oid(classId);
172  int nameCacheId = get_object_catcache_name(classId);
173  AttrNumber Anum_name = get_object_attnum_name(classId);
174  AttrNumber Anum_namespace = get_object_attnum_namespace(classId);
175  AttrNumber Anum_owner = get_object_attnum_owner(classId);
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)))
228  old_name);
229 
230  /* User must have CREATE privilege on the namespace */
231  if (OidIsValid(namespaceId))
232  {
233  aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(),
234  ACL_CREATE);
235  if (aclresult != ACLCHECK_OK)
236  aclcheck_error(aclresult, OBJECT_SCHEMA,
237  get_namespace_name(namespaceId));
238  }
239 
240  if (classId == SubscriptionRelationId)
241  {
243 
244  /* must have CREATE privilege on database */
245  aclresult = object_aclcheck(DatabaseRelationId, MyDatabaseId,
246  GetUserId(), ACL_CREATE);
247  if (aclresult != ACLCHECK_OK)
248  aclcheck_error(aclresult, OBJECT_DATABASE,
250 
251  /*
252  * Don't allow non-superuser modification of a subscription with
253  * password_required=false.
254  */
255  form = (Form_pg_subscription) GETSTRUCT(oldtup);
256  if (!form->subpasswordrequired && !superuser())
257  ereport(ERROR,
258  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
259  errmsg("password_required=false is superuser-only"),
260  errhint("Subscriptions with the password_required option set to false may only be created or modified by the superuser.")));
261  }
262  }
263 
264  /*
265  * Check for duplicate name (more friendly than unique-index failure).
266  * Since this is just a friendliness check, we can just skip it in cases
267  * where there isn't suitable support.
268  */
269  if (classId == ProcedureRelationId)
270  {
271  Form_pg_proc proc = (Form_pg_proc) GETSTRUCT(oldtup);
272 
273  IsThereFunctionInNamespace(new_name, proc->pronargs,
274  &proc->proargtypes, proc->pronamespace);
275  }
276  else if (classId == CollationRelationId)
277  {
279 
280  IsThereCollationInNamespace(new_name, coll->collnamespace);
281  }
282  else if (classId == OperatorClassRelationId)
283  {
284  Form_pg_opclass opc = (Form_pg_opclass) GETSTRUCT(oldtup);
285 
286  IsThereOpClassInNamespace(new_name, opc->opcmethod,
287  opc->opcnamespace);
288  }
289  else if (classId == OperatorFamilyRelationId)
290  {
292 
293  IsThereOpFamilyInNamespace(new_name, opf->opfmethod,
294  opf->opfnamespace);
295  }
296  else if (classId == SubscriptionRelationId)
297  {
300  CStringGetDatum(new_name)))
301  report_name_conflict(classId, new_name);
302 
303  /* Also enforce regression testing naming rules, if enabled */
304 #ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS
305  if (strncmp(new_name, "regress_", 8) != 0)
306  elog(WARNING, "subscriptions created by regression test cases should have names starting with \"regress_\"");
307 #endif
308 
309  /* Wake up related replication workers to handle this change quickly */
311  }
312  else if (nameCacheId >= 0)
313  {
314  if (OidIsValid(namespaceId))
315  {
316  if (SearchSysCacheExists2(nameCacheId,
317  CStringGetDatum(new_name),
318  ObjectIdGetDatum(namespaceId)))
319  report_namespace_conflict(classId, new_name, namespaceId);
320  }
321  else
322  {
323  if (SearchSysCacheExists1(nameCacheId,
324  CStringGetDatum(new_name)))
325  report_name_conflict(classId, new_name);
326  }
327  }
328 
329  /* Build modified tuple */
331  nulls = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
332  replaces = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
333  namestrcpy(&nameattrdata, new_name);
334  values[Anum_name - 1] = NameGetDatum(&nameattrdata);
335  replaces[Anum_name - 1] = true;
336  newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel),
337  values, nulls, replaces);
338 
339  /* Perform actual update */
340  CatalogTupleUpdate(rel, &oldtup->t_self, newtup);
341 
342  InvokeObjectPostAlterHook(classId, objectId, 0);
343 
344  /* Release memory */
345  pfree(values);
346  pfree(nulls);
347  pfree(replaces);
348  heap_freetuple(newtup);
349 
350  ReleaseSysCache(oldtup);
351 }
static void report_name_conflict(Oid classId, const char *name)
Definition: alter.c:79
void LogicalRepWorkersWakeupAtCommit(Oid subid)
Definition: worker.c:4989
char * get_database_name(Oid dbid)
Definition: dbcommands.c:3084
int errhint(const char *fmt,...)
Definition: elog.c:1316
#define WARNING
Definition: elog.h:36
Oid MyDatabaseId
Definition: globals.c:89
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1426
void namestrcpy(Name name, const char *str)
Definition: name.c:233
@ OBJECT_DATABASE
Definition: parsenodes.h:2129
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:730
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:868
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:820
@ SUBSCRIPTIONNAME
Definition: syscache.h:98
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:191

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, SUBSCRIPTIONNAME, superuser(), HeapTupleData::t_self, values, and WARNING.

Referenced by ExecRenameStmt().

◆ ExecAlterObjectDependsStmt()

ObjectAddress ExecAlterObjectDependsStmt ( AlterObjectDependsStmt stmt,
ObjectAddress refAddress 
)

Definition at line 460 of file alter.c.

461 {
462  ObjectAddress address;
463  ObjectAddress refAddr;
464  Relation rel;
465 
466  address =
467  get_object_address_rv(stmt->objectType, stmt->relation, (List *) stmt->object,
468  &rel, AccessExclusiveLock, false);
469 
470  /*
471  * Verify that the user is entitled to run the command.
472  *
473  * We don't check any privileges on the extension, because that's not
474  * needed. The object owner is stipulating, by running this command, that
475  * the extension owner can drop the object whenever they feel like it,
476  * which is not considered a problem.
477  */
479  stmt->objectType, address, stmt->object, rel);
480 
481  /*
482  * If a relation was involved, it would have been opened and locked. We
483  * don't need the relation here, but we'll retain the lock until commit.
484  */
485  if (rel)
486  table_close(rel, NoLock);
487 
488  refAddr = get_object_address(OBJECT_EXTENSION, (Node *) stmt->extname,
489  &rel, AccessExclusiveLock, false);
490  Assert(rel == NULL);
491  if (refAddress)
492  *refAddress = refAddr;
493 
494  if (stmt->remove)
495  {
498  refAddr.classId, refAddr.objectId);
499  }
500  else
501  {
502  List *currexts;
503 
504  /* Avoid duplicates */
505  currexts = getAutoExtensionsOfObject(address.classId,
506  address.objectId);
507  if (!list_member_oid(currexts, refAddr.objectId))
508  recordDependencyOn(&address, &refAddr, DEPENDENCY_AUTO_EXTENSION);
509  }
510 
511  return address;
512 }
@ 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:721
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:2135
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 524 of file alter.c.

526 {
527  ObjectAddress address;
528  Oid oldNspOid;
529 
530  switch (stmt->objectType)
531  {
532  case OBJECT_EXTENSION:
533  address = AlterExtensionNamespace(strVal(stmt->object), stmt->newschema,
534  oldSchemaAddr ? &oldNspOid : NULL);
535  break;
536 
538  case OBJECT_SEQUENCE:
539  case OBJECT_TABLE:
540  case OBJECT_VIEW:
541  case OBJECT_MATVIEW:
542  address = AlterTableNamespace(stmt,
543  oldSchemaAddr ? &oldNspOid : NULL);
544  break;
545 
546  case OBJECT_DOMAIN:
547  case OBJECT_TYPE:
548  address = AlterTypeNamespace(castNode(List, stmt->object), stmt->newschema,
549  stmt->objectType,
550  oldSchemaAddr ? &oldNspOid : NULL);
551  break;
552 
553  /* generic code path */
554  case OBJECT_AGGREGATE:
555  case OBJECT_COLLATION:
556  case OBJECT_CONVERSION:
557  case OBJECT_FUNCTION:
558  case OBJECT_OPERATOR:
559  case OBJECT_OPCLASS:
560  case OBJECT_OPFAMILY:
561  case OBJECT_PROCEDURE:
562  case OBJECT_ROUTINE:
565  case OBJECT_TSDICTIONARY:
566  case OBJECT_TSPARSER:
567  case OBJECT_TSTEMPLATE:
568  {
569  Relation catalog;
570  Relation relation;
571  Oid classId;
572  Oid nspOid;
573 
574  address = get_object_address(stmt->objectType,
575  stmt->object,
576  &relation,
578  false);
579  Assert(relation == NULL);
580  classId = address.classId;
581  catalog = table_open(classId, RowExclusiveLock);
582  nspOid = LookupCreationNamespace(stmt->newschema);
583 
584  oldNspOid = AlterObjectNamespace_internal(catalog, address.objectId,
585  nspOid);
586  table_close(catalog, RowExclusiveLock);
587  }
588  break;
589 
590  default:
591  elog(ERROR, "unrecognized AlterObjectSchemaStmt type: %d",
592  (int) stmt->objectType);
593  return InvalidObjectAddress; /* keep compiler happy */
594  }
595 
596  if (oldSchemaAddr)
597  ObjectAddressSet(*oldSchemaAddr, NamespaceRelationId, oldNspOid);
598 
599  return address;
600 }
ObjectAddress AlterExtensionNamespace(const char *extensionName, const char *newschema, Oid *oldschema)
Definition: extension.c:2771
Oid LookupCreationNamespace(const char *nspname)
Definition: namespace.c:2961
#define castNode(_type_, nodeptr)
Definition: nodes.h:197
const ObjectAddress InvalidObjectAddress
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
@ OBJECT_TSPARSER
Definition: parsenodes.h:2167
@ OBJECT_COLLATION
Definition: parsenodes.h:2127
@ OBJECT_OPCLASS
Definition: parsenodes.h:2144
@ OBJECT_AGGREGATE
Definition: parsenodes.h:2121
@ OBJECT_MATVIEW
Definition: parsenodes.h:2143
@ OBJECT_OPERATOR
Definition: parsenodes.h:2145
@ OBJECT_FOREIGN_TABLE
Definition: parsenodes.h:2138
@ OBJECT_TSCONFIGURATION
Definition: parsenodes.h:2165
@ OBJECT_OPFAMILY
Definition: parsenodes.h:2146
@ OBJECT_DOMAIN
Definition: parsenodes.h:2132
@ OBJECT_ROUTINE
Definition: parsenodes.h:2154
@ OBJECT_PROCEDURE
Definition: parsenodes.h:2149
@ OBJECT_SEQUENCE
Definition: parsenodes.h:2157
@ OBJECT_TSTEMPLATE
Definition: parsenodes.h:2168
@ OBJECT_TSDICTIONARY
Definition: parsenodes.h:2166
@ OBJECT_CONVERSION
Definition: parsenodes.h:2128
@ OBJECT_TABLE
Definition: parsenodes.h:2161
@ OBJECT_VIEW
Definition: parsenodes.h:2171
@ OBJECT_TYPE
Definition: parsenodes.h:2169
@ OBJECT_FUNCTION
Definition: parsenodes.h:2139
@ OBJECT_STATISTIC_EXT
Definition: parsenodes.h:2159
ObjectAddress AlterTableNamespace(AlterObjectSchemaStmt *stmt, Oid *oldschema)
Definition: tablecmds.c:17164
ObjectAddress AlterTypeNamespace(List *names, const char *newschema, ObjectType objecttype, Oid *oldschema)
Definition: typecmds.c:3871
#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 867 of file alter.c.

868 {
869  Oid newowner = get_rolespec_oid(stmt->newowner, false);
870 
871  switch (stmt->objectType)
872  {
873  case OBJECT_DATABASE:
874  return AlterDatabaseOwner(strVal(stmt->object), newowner);
875 
876  case OBJECT_SCHEMA:
877  return AlterSchemaOwner(strVal(stmt->object), newowner);
878 
879  case OBJECT_TYPE:
880  case OBJECT_DOMAIN: /* same as TYPE */
881  return AlterTypeOwner(castNode(List, stmt->object), newowner, stmt->objectType);
882  break;
883 
884  case OBJECT_FDW:
885  return AlterForeignDataWrapperOwner(strVal(stmt->object),
886  newowner);
887 
889  return AlterForeignServerOwner(strVal(stmt->object),
890  newowner);
891 
893  return AlterEventTriggerOwner(strVal(stmt->object),
894  newowner);
895 
896  case OBJECT_PUBLICATION:
897  return AlterPublicationOwner(strVal(stmt->object),
898  newowner);
899 
900  case OBJECT_SUBSCRIPTION:
901  return AlterSubscriptionOwner(strVal(stmt->object),
902  newowner);
903 
904  /* Generic cases */
905  case OBJECT_AGGREGATE:
906  case OBJECT_COLLATION:
907  case OBJECT_CONVERSION:
908  case OBJECT_FUNCTION:
909  case OBJECT_LANGUAGE:
910  case OBJECT_LARGEOBJECT:
911  case OBJECT_OPERATOR:
912  case OBJECT_OPCLASS:
913  case OBJECT_OPFAMILY:
914  case OBJECT_PROCEDURE:
915  case OBJECT_ROUTINE:
917  case OBJECT_TABLESPACE:
918  case OBJECT_TSDICTIONARY:
920  {
921  Relation catalog;
922  Relation relation;
923  Oid classId;
924  ObjectAddress address;
925 
926  address = get_object_address(stmt->objectType,
927  stmt->object,
928  &relation,
930  false);
931  Assert(relation == NULL);
932  classId = address.classId;
933 
934  /*
935  * XXX - get_object_address returns Oid of pg_largeobject
936  * catalog for OBJECT_LARGEOBJECT because of historical
937  * reasons. Fix up it here.
938  */
939  if (classId == LargeObjectRelationId)
940  classId = LargeObjectMetadataRelationId;
941 
942  catalog = table_open(classId, RowExclusiveLock);
943 
944  AlterObjectOwner_internal(catalog, address.objectId, newowner);
945  table_close(catalog, RowExclusiveLock);
946 
947  return address;
948  }
949  break;
950 
951  default:
952  elog(ERROR, "unrecognized AlterOwnerStmt type: %d",
953  (int) stmt->objectType);
954  return InvalidObjectAddress; /* keep compiler happy */
955  }
956 }
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5281
void AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId)
Definition: alter.c:968
ObjectAddress AlterDatabaseOwner(const char *dbname, Oid newOwnerId)
Definition: dbcommands.c:2545
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:2134
@ OBJECT_FDW
Definition: parsenodes.h:2136
@ OBJECT_TABLESPACE
Definition: parsenodes.h:2162
@ OBJECT_LARGEOBJECT
Definition: parsenodes.h:2142
@ OBJECT_LANGUAGE
Definition: parsenodes.h:2141
@ OBJECT_FOREIGN_SERVER
Definition: parsenodes.h:2137
@ OBJECT_PUBLICATION
Definition: parsenodes.h:2150
@ OBJECT_SUBSCRIPTION
Definition: parsenodes.h:2158
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:3668

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, RowExclusiveLock, stmt, strVal, table_close(), and table_open().

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

◆ ExecRenameStmt()

ObjectAddress ExecRenameStmt ( RenameStmt stmt)

Definition at line 360 of file alter.c.

361 {
362  switch (stmt->renameType)
363  {
366  return RenameConstraint(stmt);
367 
368  case OBJECT_DATABASE:
369  return RenameDatabase(stmt->subname, stmt->newname);
370 
371  case OBJECT_ROLE:
372  return RenameRole(stmt->subname, stmt->newname);
373 
374  case OBJECT_SCHEMA:
375  return RenameSchema(stmt->subname, stmt->newname);
376 
377  case OBJECT_TABLESPACE:
378  return RenameTableSpace(stmt->subname, stmt->newname);
379 
380  case OBJECT_TABLE:
381  case OBJECT_SEQUENCE:
382  case OBJECT_VIEW:
383  case OBJECT_MATVIEW:
384  case OBJECT_INDEX:
386  return RenameRelation(stmt);
387 
388  case OBJECT_COLUMN:
389  case OBJECT_ATTRIBUTE:
390  return renameatt(stmt);
391 
392  case OBJECT_RULE:
393  return RenameRewriteRule(stmt->relation, stmt->subname,
394  stmt->newname);
395 
396  case OBJECT_TRIGGER:
397  return renametrig(stmt);
398 
399  case OBJECT_POLICY:
400  return rename_policy(stmt);
401 
402  case OBJECT_DOMAIN:
403  case OBJECT_TYPE:
404  return RenameType(stmt);
405 
406  case OBJECT_AGGREGATE:
407  case OBJECT_COLLATION:
408  case OBJECT_CONVERSION:
410  case OBJECT_FDW:
412  case OBJECT_FUNCTION:
413  case OBJECT_OPCLASS:
414  case OBJECT_OPFAMILY:
415  case OBJECT_LANGUAGE:
416  case OBJECT_PROCEDURE:
417  case OBJECT_ROUTINE:
420  case OBJECT_TSDICTIONARY:
421  case OBJECT_TSPARSER:
422  case OBJECT_TSTEMPLATE:
423  case OBJECT_PUBLICATION:
424  case OBJECT_SUBSCRIPTION:
425  {
426  ObjectAddress address;
427  Relation catalog;
428  Relation relation;
429 
430  address = get_object_address(stmt->renameType,
431  stmt->object,
432  &relation,
433  AccessExclusiveLock, false);
434  Assert(relation == NULL);
435 
436  catalog = table_open(address.classId, RowExclusiveLock);
438  address.objectId,
439  stmt->newname);
440  table_close(catalog, RowExclusiveLock);
441 
442  return address;
443  }
444 
445  default:
446  elog(ERROR, "unrecognized rename stmt type: %d",
447  (int) stmt->renameType);
448  return InvalidObjectAddress; /* keep compiler happy */
449  }
450 }
static void AlterObjectRename_internal(Relation rel, Oid objectId, const char *new_name)
Definition: alter.c:168
ObjectAddress RenameTableSpace(const char *oldname, const char *newname)
Definition: tablespace.c:936
ObjectAddress RenameRole(const char *oldname, const char *newname)
Definition: user.c:1341
ObjectAddress RenameDatabase(const char *oldname, const char *newname)
Definition: dbcommands.c:1805
@ OBJECT_POLICY
Definition: parsenodes.h:2148
@ OBJECT_COLUMN
Definition: parsenodes.h:2126
@ OBJECT_ROLE
Definition: parsenodes.h:2153
@ OBJECT_INDEX
Definition: parsenodes.h:2140
@ OBJECT_ATTRIBUTE
Definition: parsenodes.h:2124
@ OBJECT_RULE
Definition: parsenodes.h:2155
@ OBJECT_TABCONSTRAINT
Definition: parsenodes.h:2160
@ OBJECT_DOMCONSTRAINT
Definition: parsenodes.h:2133
@ OBJECT_TRIGGER
Definition: parsenodes.h:2164
ObjectAddress rename_policy(RenameStmt *stmt)
Definition: policy.c:1099
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:3998
ObjectAddress renameatt(RenameStmt *stmt)
Definition: tablecmds.c:3801
ObjectAddress RenameConstraint(RenameStmt *stmt)
Definition: tablecmds.c:3948
ObjectAddress renametrig(RenameStmt *stmt)
Definition: trigger.c:1469
ObjectAddress RenameType(RenameStmt *stmt)
Definition: typecmds.c:3591

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 79 of file alter.c.

80 {
81  char *msgfmt;
82 
83  switch (classId)
84  {
85  case EventTriggerRelationId:
86  msgfmt = gettext_noop("event trigger \"%s\" already exists");
87  break;
88  case ForeignDataWrapperRelationId:
89  msgfmt = gettext_noop("foreign-data wrapper \"%s\" already exists");
90  break;
91  case ForeignServerRelationId:
92  msgfmt = gettext_noop("server \"%s\" already exists");
93  break;
94  case LanguageRelationId:
95  msgfmt = gettext_noop("language \"%s\" already exists");
96  break;
97  case PublicationRelationId:
98  msgfmt = gettext_noop("publication \"%s\" already exists");
99  break;
100  case SubscriptionRelationId:
101  msgfmt = gettext_noop("subscription \"%s\" already exists");
102  break;
103  default:
104  elog(ERROR, "unsupported object class: %u", classId);
105  break;
106  }
107 
108  ereport(ERROR,
110  errmsg(msgfmt, name)));
111 }
#define gettext_noop(x)
Definition: c.h:1209
#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 114 of file alter.c.

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

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().