PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
alter.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/sysattr.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 "utils/tqual.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

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

Definition at line 654 of file alter.c.

References ACL_CREATE, ACL_KIND_NAMESPACE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, Assert, CatalogTupleUpdate(), changeDependencyFor(), CheckSetNamespace(), CollationRelationId, DatumGetName, DatumGetObjectId, elog, ereport, errcode(), errmsg(), ERROR, get_namespace_name(), get_object_aclkind(), get_object_attnum_name(), get_object_attnum_namespace(), get_object_attnum_owner(), get_object_catcache_name(), get_object_catcache_oid(), getObjectDescriptionOids(), GETSTRUCT, GetUserId(), has_privs_of_role(), heap_getattr, heap_modify_tuple(), HeapTupleIsValid, InvokeObjectPostAlterHook, IsThereCollationInNamespace(), IsThereFunctionInNamespace(), IsThereOpClassInNamespace(), IsThereOpFamilyInNamespace(), name, NamespaceRelationId, NameStr, ObjectIdGetDatum, OperatorClassRelationId, OperatorFamilyRelationId, palloc0(), pfree(), pg_namespace_aclcheck(), ProcedureRelationId, RelationGetDescr, RelationGetNumberOfAttributes, RelationGetRelationName, RelationGetRelid, report_namespace_conflict(), SearchSysCacheCopy1, SearchSysCacheExists2, superuser(), and values.

Referenced by AlterObjectNamespace_oid(), and ExecAlterObjectSchemaStmt().

655 {
656  Oid classId = RelationGetRelid(rel);
657  int oidCacheId = get_object_catcache_oid(classId);
658  int nameCacheId = get_object_catcache_name(classId);
659  AttrNumber Anum_name = get_object_attnum_name(classId);
660  AttrNumber Anum_namespace = get_object_attnum_namespace(classId);
661  AttrNumber Anum_owner = get_object_attnum_owner(classId);
662  AclObjectKind acl_kind = get_object_aclkind(classId);
663  Oid oldNspOid;
664  Datum name,
665  namespace;
666  bool isnull;
667  HeapTuple tup,
668  newtup;
669  Datum *values;
670  bool *nulls;
671  bool *replaces;
672 
673  tup = SearchSysCacheCopy1(oidCacheId, ObjectIdGetDatum(objid));
674  if (!HeapTupleIsValid(tup)) /* should not happen */
675  elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
676  objid, RelationGetRelationName(rel));
677 
678  name = heap_getattr(tup, Anum_name, RelationGetDescr(rel), &isnull);
679  Assert(!isnull);
680  namespace = heap_getattr(tup, Anum_namespace, RelationGetDescr(rel),
681  &isnull);
682  Assert(!isnull);
683  oldNspOid = DatumGetObjectId(namespace);
684 
685  /*
686  * If the object is already in the correct namespace, we don't need to do
687  * anything except fire the object access hook.
688  */
689  if (oldNspOid == nspOid)
690  {
691  InvokeObjectPostAlterHook(classId, objid, 0);
692  return oldNspOid;
693  }
694 
695  /* Check basic namespace related issues */
696  CheckSetNamespace(oldNspOid, nspOid);
697 
698  /* Permission checks ... superusers can always do it */
699  if (!superuser())
700  {
701  Datum owner;
702  Oid ownerId;
703  AclResult aclresult;
704 
705  /* Fail if object does not have an explicit owner */
706  if (Anum_owner <= 0)
707  ereport(ERROR,
708  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
709  (errmsg("must be superuser to set schema of %s",
710  getObjectDescriptionOids(classId, objid)))));
711 
712  /* Otherwise, must be owner of the existing object */
713  owner = heap_getattr(tup, Anum_owner, RelationGetDescr(rel), &isnull);
714  Assert(!isnull);
715  ownerId = DatumGetObjectId(owner);
716 
717  if (!has_privs_of_role(GetUserId(), ownerId))
719  NameStr(*(DatumGetName(name))));
720 
721  /* User must have CREATE privilege on new namespace */
722  aclresult = pg_namespace_aclcheck(nspOid, GetUserId(), ACL_CREATE);
723  if (aclresult != ACLCHECK_OK)
725  get_namespace_name(nspOid));
726  }
727 
728  /*
729  * Check for duplicate name (more friendly than unique-index failure).
730  * Since this is just a friendliness check, we can just skip it in cases
731  * where there isn't suitable support.
732  */
733  if (classId == ProcedureRelationId)
734  {
735  Form_pg_proc proc = (Form_pg_proc) GETSTRUCT(tup);
736 
737  IsThereFunctionInNamespace(NameStr(proc->proname), proc->pronargs,
738  &proc->proargtypes, nspOid);
739  }
740  else if (classId == CollationRelationId)
741  {
743 
744  IsThereCollationInNamespace(NameStr(coll->collname), nspOid);
745  }
746  else if (classId == OperatorClassRelationId)
747  {
749 
750  IsThereOpClassInNamespace(NameStr(opc->opcname),
751  opc->opcmethod, nspOid);
752  }
753  else if (classId == OperatorFamilyRelationId)
754  {
756 
757  IsThereOpFamilyInNamespace(NameStr(opf->opfname),
758  opf->opfmethod, nspOid);
759  }
760  else if (nameCacheId >= 0 &&
761  SearchSysCacheExists2(nameCacheId, name,
762  ObjectIdGetDatum(nspOid)))
764  NameStr(*(DatumGetName(name))),
765  nspOid);
766 
767  /* Build modified tuple */
768  values = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(Datum));
769  nulls = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
770  replaces = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
771  values[Anum_namespace - 1] = ObjectIdGetDatum(nspOid);
772  replaces[Anum_namespace - 1] = true;
773  newtup = heap_modify_tuple(tup, RelationGetDescr(rel),
774  values, nulls, replaces);
775 
776  /* Perform actual update */
777  CatalogTupleUpdate(rel, &tup->t_self, newtup);
778 
779  /* Release memory */
780  pfree(values);
781  pfree(nulls);
782  pfree(replaces);
783 
784  /* update dependencies to point to the new schema */
785  changeDependencyFor(classId, objid,
786  NamespaceRelationId, oldNspOid, nspOid);
787 
788  InvokeObjectPostAlterHook(classId, objid, 0);
789 
790  return oldNspOid;
791 }
#define NamespaceRelationId
Definition: pg_namespace.h:34
static void report_namespace_conflict(Oid classId, const char *name, Oid nspOid)
Definition: alter.c:112
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
AttrNumber get_object_attnum_owner(Oid class_id)
#define RelationGetDescr(relation)
Definition: rel.h:428
Oid GetUserId(void)
Definition: miscinit.c:283
#define RelationGetNumberOfAttributes(relation)
Definition: rel.h:422
#define ProcedureRelationId
Definition: pg_proc.h:33
#define DatumGetObjectId(X)
Definition: postgres.h:506
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4813
int get_object_catcache_name(Oid class_id)
#define OperatorClassRelationId
Definition: pg_opclass.h:49
#define OperatorFamilyRelationId
Definition: pg_opfamily.h:29
int errcode(int sqlerrcode)
Definition: elog.c:575
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:4484
void IsThereOpClassInNamespace(const char *opcname, Oid opcmethod, Oid opcnamespace)
Definition: opclasscmds.c:1649
#define DatumGetName(X)
Definition: postgres.h:591
void pfree(void *pointer)
Definition: mcxt.c:950
AclObjectKind get_object_aclkind(Oid class_id)
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ACL_CREATE
Definition: parsenodes.h:82
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:3033
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3399
#define RelationGetRelationName(relation)
Definition: rel.h:436
void IsThereCollationInNamespace(const char *collname, Oid nspOid)
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
void CheckSetNamespace(Oid oldNspOid, Oid nspOid)
Definition: namespace.c:2885
void IsThereFunctionInNamespace(const char *proname, int pronargs, oidvector *proargtypes, Oid nspOid)
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:769
FormData_pg_opfamily * Form_pg_opfamily
Definition: pg_opfamily.h:44
AttrNumber get_object_attnum_name(Oid class_id)
void * palloc0(Size size)
Definition: mcxt.c:878
AclResult
Definition: acl.h:170
uintptr_t Datum
Definition: postgres.h:372
#define CollationRelationId
Definition: pg_collation.h:30
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:83
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define Assert(condition)
Definition: c.h:675
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:176
const char * name
Definition: encode.c:521
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:52
static Datum values[MAXATTR]
Definition: bootstrap.c:163
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:165
int errmsg(const char *fmt,...)
Definition: elog.c:797
long changeDependencyFor(Oid classId, Oid objectId, Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId)
Definition: pg_depend.c:295
#define NameStr(name)
Definition: c.h:499
#define elog
Definition: elog.h:219
AclObjectKind
Definition: acl.h:179
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:791
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:68
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:1672
Oid AlterObjectNamespace_oid ( Oid  classId,
Oid  objid,
Oid  nspOid,
ObjectAddresses objsMoved 
)

Definition at line 553 of file alter.c.

References AccessExclusiveLock, AlterObjectNamespace_internal(), AlterTableNamespaceInternal(), AlterTypeNamespace_oid(), ObjectAddress::classId, getObjectClass(), heap_close, heap_open(), 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, and RowExclusiveLock.

Referenced by AlterExtensionNamespace().

555 {
556  Oid oldNspOid = InvalidOid;
557  ObjectAddress dep;
558 
559  dep.classId = classId;
560  dep.objectId = objid;
561  dep.objectSubId = 0;
562 
563  switch (getObjectClass(&dep))
564  {
565  case OCLASS_CLASS:
566  {
567  Relation rel;
568 
569  rel = relation_open(objid, AccessExclusiveLock);
570  oldNspOid = RelationGetNamespace(rel);
571 
572  AlterTableNamespaceInternal(rel, oldNspOid, nspOid, objsMoved);
573 
574  relation_close(rel, NoLock);
575  break;
576  }
577 
578  case OCLASS_TYPE:
579  oldNspOid = AlterTypeNamespace_oid(objid, nspOid, objsMoved);
580  break;
581 
582  case OCLASS_PROC:
583  case OCLASS_COLLATION:
584  case OCLASS_CONVERSION:
585  case OCLASS_OPERATOR:
586  case OCLASS_OPCLASS:
587  case OCLASS_OPFAMILY:
589  case OCLASS_TSPARSER:
590  case OCLASS_TSDICT:
591  case OCLASS_TSTEMPLATE:
592  case OCLASS_TSCONFIG:
593  {
594  Relation catalog;
595 
596  catalog = heap_open(classId, RowExclusiveLock);
597 
598  oldNspOid = AlterObjectNamespace_internal(catalog, objid,
599  nspOid);
600 
601  heap_close(catalog, RowExclusiveLock);
602  }
603  break;
604 
605  case OCLASS_CAST:
606  case OCLASS_CONSTRAINT:
607  case OCLASS_DEFAULT:
608  case OCLASS_LANGUAGE:
609  case OCLASS_LARGEOBJECT:
610  case OCLASS_AM:
611  case OCLASS_AMOP:
612  case OCLASS_AMPROC:
613  case OCLASS_REWRITE:
614  case OCLASS_TRIGGER:
615  case OCLASS_SCHEMA:
616  case OCLASS_ROLE:
617  case OCLASS_DATABASE:
618  case OCLASS_TBLSPACE:
619  case OCLASS_FDW:
621  case OCLASS_USER_MAPPING:
622  case OCLASS_DEFACL:
623  case OCLASS_EXTENSION:
625  case OCLASS_POLICY:
626  case OCLASS_PUBLICATION:
628  case OCLASS_SUBSCRIPTION:
629  case OCLASS_TRANSFORM:
630  /* ignore object types that don't have schema-qualified names */
631  break;
632 
633  /*
634  * There's intentionally no default: case here; we want the
635  * compiler to warn if a new OCLASS hasn't been handled above.
636  */
637  }
638 
639  return oldNspOid;
640 }
static Oid AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
Definition: alter.c:654
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1260
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
ObjectClass getObjectClass(const ObjectAddress *object)
Definition: dependency.c:2338
void AlterTableNamespaceInternal(Relation rel, Oid oldNspOid, Oid nspOid, ObjectAddresses *objsMoved)
Definition: tablecmds.c:12488
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
Oid AlterTypeNamespace_oid(Oid typeOid, Oid nspOid, ObjectAddresses *objsMoved)
Definition: typecmds.c:3453
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define InvalidOid
Definition: postgres_ext.h:36
#define AccessExclusiveLock
Definition: lockdefs.h:45
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1114
#define RelationGetNamespace(relation)
Definition: rel.h:443
void AlterObjectOwner_internal ( Relation  rel,
Oid  objectId,
Oid  new_ownerId 
)

Definition at line 897 of file alter.c.

References ACL_CREATE, ACL_KIND_NAMESPACE, 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_aclkind(), get_object_attnum_acl(), get_object_attnum_name(), get_object_attnum_namespace(), get_object_attnum_owner(), GetUserId(), has_privs_of_role(), heap_getattr, heap_modify_tuple(), HeapTupleGetOid, InvalidAttrNumber, InvalidOid, InvokeObjectPostAlterHook, LargeObjectMetadataRelationId, LargeObjectRelationId, NAMEDATALEN, NameStr, NULL, ObjectIdGetDatum, OidIsValid, palloc0(), pfree(), pg_namespace_aclcheck(), PointerGetDatum, RelationGetDescr, RelationGetNumberOfAttributes, RelationGetRelationName, RelationGetRelid, snprintf(), superuser(), HeapTupleData::t_self, and values.

Referenced by ExecAlterOwnerStmt(), and shdepReassignOwned().

898 {
899  Oid classId = RelationGetRelid(rel);
900  AttrNumber Anum_owner = get_object_attnum_owner(classId);
901  AttrNumber Anum_namespace = get_object_attnum_namespace(classId);
902  AttrNumber Anum_acl = get_object_attnum_acl(classId);
903  AttrNumber Anum_name = get_object_attnum_name(classId);
904  HeapTuple oldtup;
905  Datum datum;
906  bool isnull;
907  Oid old_ownerId;
908  Oid namespaceId = InvalidOid;
909 
910  oldtup = get_catalog_object_by_oid(rel, objectId);
911  if (oldtup == NULL)
912  elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
913  objectId, RelationGetRelationName(rel));
914 
915  datum = heap_getattr(oldtup, Anum_owner,
916  RelationGetDescr(rel), &isnull);
917  Assert(!isnull);
918  old_ownerId = DatumGetObjectId(datum);
919 
920  if (Anum_namespace != InvalidAttrNumber)
921  {
922  datum = heap_getattr(oldtup, Anum_namespace,
923  RelationGetDescr(rel), &isnull);
924  Assert(!isnull);
925  namespaceId = DatumGetObjectId(datum);
926  }
927 
928  if (old_ownerId != new_ownerId)
929  {
930  AttrNumber nattrs;
931  HeapTuple newtup;
932  Datum *values;
933  bool *nulls;
934  bool *replaces;
935 
936  /* Superusers can bypass permission checks */
937  if (!superuser())
938  {
939  AclObjectKind aclkind = get_object_aclkind(classId);
940 
941  /* must be owner */
942  if (!has_privs_of_role(GetUserId(), old_ownerId))
943  {
944  char *objname;
945  char namebuf[NAMEDATALEN];
946 
947  if (Anum_name != InvalidAttrNumber)
948  {
949  datum = heap_getattr(oldtup, Anum_name,
950  RelationGetDescr(rel), &isnull);
951  Assert(!isnull);
952  objname = NameStr(*DatumGetName(datum));
953  }
954  else
955  {
956  snprintf(namebuf, sizeof(namebuf), "%u",
957  HeapTupleGetOid(oldtup));
958  objname = namebuf;
959  }
960  aclcheck_error(ACLCHECK_NOT_OWNER, aclkind, objname);
961  }
962  /* Must be able to become new owner */
963  check_is_member_of_role(GetUserId(), new_ownerId);
964 
965  /* New owner must have CREATE privilege on namespace */
966  if (OidIsValid(namespaceId))
967  {
968  AclResult aclresult;
969 
970  aclresult = pg_namespace_aclcheck(namespaceId, new_ownerId,
971  ACL_CREATE);
972  if (aclresult != ACLCHECK_OK)
974  get_namespace_name(namespaceId));
975  }
976  }
977 
978  /* Build a modified tuple */
979  nattrs = RelationGetNumberOfAttributes(rel);
980  values = palloc0(nattrs * sizeof(Datum));
981  nulls = palloc0(nattrs * sizeof(bool));
982  replaces = palloc0(nattrs * sizeof(bool));
983  values[Anum_owner - 1] = ObjectIdGetDatum(new_ownerId);
984  replaces[Anum_owner - 1] = true;
985 
986  /*
987  * Determine the modified ACL for the new owner. This is only
988  * necessary when the ACL is non-null.
989  */
990  if (Anum_acl != InvalidAttrNumber)
991  {
992  datum = heap_getattr(oldtup,
993  Anum_acl, RelationGetDescr(rel), &isnull);
994  if (!isnull)
995  {
996  Acl *newAcl;
997 
998  newAcl = aclnewowner(DatumGetAclP(datum),
999  old_ownerId, new_ownerId);
1000  values[Anum_acl - 1] = PointerGetDatum(newAcl);
1001  replaces[Anum_acl - 1] = true;
1002  }
1003  }
1004 
1005  newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel),
1006  values, nulls, replaces);
1007 
1008  /* Perform actual update */
1009  CatalogTupleUpdate(rel, &newtup->t_self, newtup);
1010 
1011  /* Update owner dependency reference */
1012  if (classId == LargeObjectMetadataRelationId)
1013  classId = LargeObjectRelationId;
1014  changeDependencyOnOwner(classId, HeapTupleGetOid(newtup), new_ownerId);
1015 
1016  /* Release memory */
1017  pfree(values);
1018  pfree(nulls);
1019  pfree(replaces);
1020  }
1021 
1022  InvokeObjectPostAlterHook(classId, objectId, 0);
1023 }
AttrNumber get_object_attnum_owner(Oid class_id)
#define RelationGetDescr(relation)
Definition: rel.h:428
Oid GetUserId(void)
Definition: miscinit.c:283
#define RelationGetNumberOfAttributes(relation)
Definition: rel.h:422
#define DatumGetAclP(X)
Definition: acl.h:113
#define PointerGetDatum(X)
Definition: postgres.h:562
#define DatumGetObjectId(X)
Definition: postgres.h:506
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4813
bool superuser(void)
Definition: superuser.c:47
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
AttrNumber get_object_attnum_namespace(Oid class_id)
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4484
#define NAMEDATALEN
#define DatumGetName(X)
Definition: postgres.h:591
void changeDependencyOnOwner(Oid classId, Oid objectId, Oid newOwnerId)
Definition: pg_shdepend.c:304
void pfree(void *pointer)
Definition: mcxt.c:950
AclObjectKind get_object_aclkind(Oid class_id)
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ACL_CREATE
Definition: parsenodes.h:82
ItemPointerData t_self
Definition: htup.h:65
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3033
AttrNumber get_object_attnum_acl(Oid class_id)
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3399
#define RelationGetRelationName(relation)
Definition: rel.h:436
void check_is_member_of_role(Oid member, Oid role)
Definition: acl.c:4859
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:769
AttrNumber get_object_attnum_name(Oid class_id)
void * palloc0(Size size)
Definition: mcxt.c:878
AclResult
Definition: acl.h:170
uintptr_t Datum
Definition: postgres.h:372
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#define LargeObjectMetadataRelationId
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
HeapTuple get_catalog_object_by_oid(Relation catalog, Oid objectId)
#define InvalidAttrNumber
Definition: attnum.h:23
static Datum values[MAXATTR]
Definition: bootstrap.c:163
#define NameStr(name)
Definition: c.h:499
#define elog
Definition: elog.h:219
AclObjectKind
Definition: acl.h:179
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:791
#define LargeObjectRelationId
Acl * aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
Definition: acl.c:1035
int16 AttrNumber
Definition: attnum.h:21
#define RelationGetRelid(relation)
Definition: rel.h:416
static void AlterObjectRename_internal ( Relation  rel,
Oid  objectId,
const char *  new_name 
)
static

Definition at line 166 of file alter.c.

References ACL_CREATE, ACL_KIND_NAMESPACE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, Assert, CatalogTupleUpdate(), CollationRelationId, CStringGetDatum, DatumGetName, DatumGetObjectId, elog, ereport, errcode(), errmsg(), ERROR, get_namespace_name(), get_object_aclkind(), get_object_attnum_name(), get_object_attnum_namespace(), get_object_attnum_owner(), get_object_catcache_name(), get_object_catcache_oid(), 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(), ObjectIdGetDatum, OidIsValid, OperatorClassRelationId, OperatorFamilyRelationId, palloc0(), pfree(), pg_namespace_aclcheck(), ProcedureRelationId, RelationGetDescr, RelationGetNumberOfAttributes, RelationGetRelationName, RelationGetRelid, ReleaseSysCache(), report_name_conflict(), report_namespace_conflict(), SearchSysCache1, SearchSysCacheExists1, SearchSysCacheExists2, SUBSCRIPTIONNAME, SubscriptionRelationId, superuser(), HeapTupleData::t_self, and values.

Referenced by ExecRenameStmt().

167 {
168  Oid classId = RelationGetRelid(rel);
169  int oidCacheId = get_object_catcache_oid(classId);
170  int nameCacheId = get_object_catcache_name(classId);
171  AttrNumber Anum_name = get_object_attnum_name(classId);
172  AttrNumber Anum_namespace = get_object_attnum_namespace(classId);
173  AttrNumber Anum_owner = get_object_attnum_owner(classId);
174  AclObjectKind acl_kind = get_object_aclkind(classId);
175  HeapTuple oldtup;
176  HeapTuple newtup;
177  Datum datum;
178  bool isnull;
179  Oid namespaceId;
180  Oid ownerId;
181  char *old_name;
182  AclResult aclresult;
183  Datum *values;
184  bool *nulls;
185  bool *replaces;
186  NameData nameattrdata;
187 
188  oldtup = SearchSysCache1(oidCacheId, ObjectIdGetDatum(objectId));
189  if (!HeapTupleIsValid(oldtup))
190  elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
191  objectId, RelationGetRelationName(rel));
192 
193  datum = heap_getattr(oldtup, Anum_name,
194  RelationGetDescr(rel), &isnull);
195  Assert(!isnull);
196  old_name = NameStr(*(DatumGetName(datum)));
197 
198  /* Get OID of namespace */
199  if (Anum_namespace > 0)
200  {
201  datum = heap_getattr(oldtup, Anum_namespace,
202  RelationGetDescr(rel), &isnull);
203  Assert(!isnull);
204  namespaceId = DatumGetObjectId(datum);
205  }
206  else
207  namespaceId = InvalidOid;
208 
209  /* Permission checks ... superusers can always do it */
210  if (!superuser())
211  {
212  /* Fail if object does not have an explicit owner */
213  if (Anum_owner <= 0)
214  ereport(ERROR,
215  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
216  (errmsg("must be superuser to rename %s",
217  getObjectDescriptionOids(classId, objectId)))));
218 
219  /* Otherwise, must be owner of the existing object */
220  datum = heap_getattr(oldtup, Anum_owner,
221  RelationGetDescr(rel), &isnull);
222  Assert(!isnull);
223  ownerId = DatumGetObjectId(datum);
224 
225  if (!has_privs_of_role(GetUserId(), DatumGetObjectId(ownerId)))
226  aclcheck_error(ACLCHECK_NOT_OWNER, acl_kind, old_name);
227 
228  /* User must have CREATE privilege on the namespace */
229  if (OidIsValid(namespaceId))
230  {
231  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(),
232  ACL_CREATE);
233  if (aclresult != ACLCHECK_OK)
235  get_namespace_name(namespaceId));
236  }
237  }
238 
239  /*
240  * Check for duplicate name (more friendly than unique-index failure).
241  * Since this is just a friendliness check, we can just skip it in cases
242  * where there isn't suitable support.
243  */
244  if (classId == ProcedureRelationId)
245  {
246  Form_pg_proc proc = (Form_pg_proc) GETSTRUCT(oldtup);
247 
248  IsThereFunctionInNamespace(new_name, proc->pronargs,
249  &proc->proargtypes, proc->pronamespace);
250  }
251  else if (classId == CollationRelationId)
252  {
254 
255  IsThereCollationInNamespace(new_name, coll->collnamespace);
256  }
257  else if (classId == OperatorClassRelationId)
258  {
259  Form_pg_opclass opc = (Form_pg_opclass) GETSTRUCT(oldtup);
260 
261  IsThereOpClassInNamespace(new_name, opc->opcmethod,
262  opc->opcnamespace);
263  }
264  else if (classId == OperatorFamilyRelationId)
265  {
267 
268  IsThereOpFamilyInNamespace(new_name, opf->opfmethod,
269  opf->opfnamespace);
270  }
271  else if (classId == SubscriptionRelationId)
272  {
274  CStringGetDatum(new_name)))
275  report_name_conflict(classId, new_name);
276  }
277  else if (nameCacheId >= 0)
278  {
279  if (OidIsValid(namespaceId))
280  {
281  if (SearchSysCacheExists2(nameCacheId,
282  CStringGetDatum(new_name),
283  ObjectIdGetDatum(namespaceId)))
284  report_namespace_conflict(classId, new_name, namespaceId);
285  }
286  else
287  {
288  if (SearchSysCacheExists1(nameCacheId,
289  CStringGetDatum(new_name)))
290  report_name_conflict(classId, new_name);
291  }
292  }
293 
294  /* Build modified tuple */
295  values = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(Datum));
296  nulls = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
297  replaces = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
298  namestrcpy(&nameattrdata, new_name);
299  values[Anum_name - 1] = NameGetDatum(&nameattrdata);
300  replaces[Anum_name - 1] = true;
301  newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel),
302  values, nulls, replaces);
303 
304  /* Perform actual update */
305  CatalogTupleUpdate(rel, &oldtup->t_self, newtup);
306 
307  InvokeObjectPostAlterHook(classId, objectId, 0);
308 
309  /* Release memory */
310  pfree(values);
311  pfree(nulls);
312  pfree(replaces);
313  heap_freetuple(newtup);
314 
315  ReleaseSysCache(oldtup);
316 }
#define NameGetDatum(X)
Definition: postgres.h:601
static void report_namespace_conflict(Oid classId, const char *name, Oid nspOid)
Definition: alter.c:112
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
AttrNumber get_object_attnum_owner(Oid class_id)
#define RelationGetDescr(relation)
Definition: rel.h:428
Oid GetUserId(void)
Definition: miscinit.c:283
#define RelationGetNumberOfAttributes(relation)
Definition: rel.h:422
#define ProcedureRelationId
Definition: pg_proc.h:33
#define DatumGetObjectId(X)
Definition: postgres.h:506
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4813
int get_object_catcache_name(Oid class_id)
#define OperatorClassRelationId
Definition: pg_opclass.h:49
#define OperatorFamilyRelationId
Definition: pg_opfamily.h:29
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
AttrNumber get_object_attnum_namespace(Oid class_id)
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1372
unsigned int Oid
Definition: postgres_ext.h:31
int namestrcpy(Name name, const char *str)
Definition: name.c:216
#define OidIsValid(objectId)
Definition: c.h:538
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4484
void IsThereOpClassInNamespace(const char *opcname, Oid opcmethod, Oid opcnamespace)
Definition: opclasscmds.c:1649
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:156
#define DatumGetName(X)
Definition: postgres.h:591
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:174
void pfree(void *pointer)
Definition: mcxt.c:950
AclObjectKind get_object_aclkind(Oid class_id)
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ACL_CREATE
Definition: parsenodes.h:82
int get_object_catcache_oid(Oid class_id)
ItemPointerData t_self
Definition: htup.h:65
Definition: c.h:493
char * getObjectDescriptionOids(Oid classid, Oid objid)
#define SubscriptionRelationId
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3033
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3399
#define CStringGetDatum(X)
Definition: postgres.h:584
#define RelationGetRelationName(relation)
Definition: rel.h:436
void IsThereCollationInNamespace(const char *collname, Oid nspOid)
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
void IsThereFunctionInNamespace(const char *proname, int pronargs, oidvector *proargtypes, Oid nspOid)
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:769
FormData_pg_opfamily * Form_pg_opfamily
Definition: pg_opfamily.h:44
AttrNumber get_object_attnum_name(Oid class_id)
void * palloc0(Size size)
Definition: mcxt.c:878
AclResult
Definition: acl.h:170
uintptr_t Datum
Definition: postgres.h:372
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
Oid MyDatabaseId
Definition: globals.c:77
#define CollationRelationId
Definition: pg_collation.h:30
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:83
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define Assert(condition)
Definition: c.h:675
static void report_name_conflict(Oid classId, const char *name)
Definition: alter.c:77
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:176
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:52
static Datum values[MAXATTR]
Definition: bootstrap.c:163
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define NameStr(name)
Definition: c.h:499
#define elog
Definition: elog.h:219
AclObjectKind
Definition: acl.h:179
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:791
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:68
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:1672
ObjectAddress ExecAlterObjectDependsStmt ( AlterObjectDependsStmt stmt,
ObjectAddress refAddress 
)

Definition at line 423 of file alter.c.

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

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

424 {
425  ObjectAddress address;
426  ObjectAddress refAddr;
427  Relation rel;
428 
429  address =
430  get_object_address_rv(stmt->objectType, stmt->relation, (List *) stmt->object,
431  &rel, AccessExclusiveLock, false);
432 
433  /*
434  * If a relation was involved, it would have been opened and locked. We
435  * don't need the relation here, but we'll retain the lock until commit.
436  */
437  if (rel)
438  heap_close(rel, NoLock);
439 
440  refAddr = get_object_address(OBJECT_EXTENSION, (Node *) stmt->extname,
441  &rel, AccessExclusiveLock, false);
442  Assert(rel == NULL);
443  if (refAddress)
444  *refAddress = refAddr;
445 
446  recordDependencyOn(&address, &refAddr, DEPENDENCY_AUTO_EXTENSION);
447 
448  return address;
449 }
Definition: nodes.h:509
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
#define heap_close(r, l)
Definition: heapam.h:97
#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 NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
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:45
ObjectAddress ExecAlterObjectSchemaStmt ( AlterObjectSchemaStmt stmt,
ObjectAddress oldSchemaAddr 
)

Definition at line 461 of file alter.c.

References AccessExclusiveLock, AlterExtensionNamespace(), AlterObjectNamespace_internal(), AlterTableNamespace(), AlterTypeNamespace(), Assert, castNode, ObjectAddress::classId, elog, ERROR, get_object_address(), heap_close, heap_open(), InvalidObjectAddress, LookupCreationNamespace(), NamespaceRelationId, AlterObjectSchemaStmt::newschema, NULL, 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_SEQUENCE, OBJECT_STATISTIC_EXT, OBJECT_TABLE, OBJECT_TSCONFIGURATION, OBJECT_TSDICTIONARY, OBJECT_TSPARSER, OBJECT_TSTEMPLATE, OBJECT_TYPE, OBJECT_VIEW, ObjectAddressSet, ObjectAddress::objectId, AlterObjectSchemaStmt::objectType, RowExclusiveLock, and strVal.

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

463 {
464  ObjectAddress address;
465  Oid oldNspOid;
466 
467  switch (stmt->objectType)
468  {
469  case OBJECT_EXTENSION:
470  address = AlterExtensionNamespace(strVal((Value *) stmt->object), stmt->newschema,
471  oldSchemaAddr ? &oldNspOid : NULL);
472  break;
473 
475  case OBJECT_SEQUENCE:
476  case OBJECT_TABLE:
477  case OBJECT_VIEW:
478  case OBJECT_MATVIEW:
479  address = AlterTableNamespace(stmt,
480  oldSchemaAddr ? &oldNspOid : NULL);
481  break;
482 
483  case OBJECT_DOMAIN:
484  case OBJECT_TYPE:
485  address = AlterTypeNamespace(castNode(List, stmt->object), stmt->newschema,
486  stmt->objectType,
487  oldSchemaAddr ? &oldNspOid : NULL);
488  break;
489 
490  /* generic code path */
491  case OBJECT_AGGREGATE:
492  case OBJECT_COLLATION:
493  case OBJECT_CONVERSION:
494  case OBJECT_FUNCTION:
495  case OBJECT_OPERATOR:
496  case OBJECT_OPCLASS:
497  case OBJECT_OPFAMILY:
500  case OBJECT_TSDICTIONARY:
501  case OBJECT_TSPARSER:
502  case OBJECT_TSTEMPLATE:
503  {
504  Relation catalog;
505  Relation relation;
506  Oid classId;
507  Oid nspOid;
508 
509  address = get_object_address(stmt->objectType,
510  stmt->object,
511  &relation,
513  false);
514  Assert(relation == NULL);
515  classId = address.classId;
516  catalog = heap_open(classId, RowExclusiveLock);
517  nspOid = LookupCreationNamespace(stmt->newschema);
518 
519  oldNspOid = AlterObjectNamespace_internal(catalog, address.objectId,
520  nspOid);
521  heap_close(catalog, RowExclusiveLock);
522  }
523  break;
524 
525  default:
526  elog(ERROR, "unrecognized AlterObjectSchemaStmt type: %d",
527  (int) stmt->objectType);
528  return InvalidObjectAddress; /* keep compiler happy */
529  }
530 
531  if (oldSchemaAddr)
532  ObjectAddressSet(*oldSchemaAddr, NamespaceRelationId, oldNspOid);
533 
534  return address;
535 }
#define NamespaceRelationId
Definition: pg_namespace.h:34
#define castNode(_type_, nodeptr)
Definition: nodes.h:578
Oid LookupCreationNamespace(const char *nspname)
Definition: namespace.c:2853
ObjectAddress AlterTypeNamespace(List *names, const char *newschema, ObjectType objecttype, Oid *oldschema)
Definition: typecmds.c:3416
#define strVal(v)
Definition: value.h:54
static Oid AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
Definition: alter.c:654
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
ObjectAddress AlterTableNamespace(AlterObjectSchemaStmt *stmt, Oid *oldschema)
Definition: tablecmds.c:12417
#define ERROR
Definition: elog.h:43
#define RowExclusiveLock
Definition: lockdefs.h:38
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
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
Definition: elog.h:219
Definition: pg_list.h:45
ObjectAddress AlterExtensionNamespace(const char *extensionName, const char *newschema, Oid *oldschema)
Definition: extension.c:2681
ObjectAddress ExecAlterOwnerStmt ( AlterOwnerStmt stmt)

Definition at line 798 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(), heap_close, heap_open(), InvalidObjectAddress, LargeObjectMetadataRelationId, LargeObjectRelationId, AlterOwnerStmt::newowner, NULL, 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_PUBLICATION, OBJECT_SCHEMA, OBJECT_STATISTIC_EXT, OBJECT_SUBSCRIPTION, OBJECT_TABLESPACE, OBJECT_TSCONFIGURATION, OBJECT_TSDICTIONARY, OBJECT_TYPE, ObjectAddress::objectId, AlterOwnerStmt::objectType, RowExclusiveLock, and strVal.

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

799 {
800  Oid newowner = get_rolespec_oid(stmt->newowner, false);
801 
802  switch (stmt->objectType)
803  {
804  case OBJECT_DATABASE:
805  return AlterDatabaseOwner(strVal((Value *) stmt->object), newowner);
806 
807  case OBJECT_SCHEMA:
808  return AlterSchemaOwner(strVal((Value *) stmt->object), newowner);
809 
810  case OBJECT_TYPE:
811  case OBJECT_DOMAIN: /* same as TYPE */
812  return AlterTypeOwner(castNode(List, stmt->object), newowner, stmt->objectType);
813  break;
814 
815  case OBJECT_FDW:
817  newowner);
818 
820  return AlterForeignServerOwner(strVal((Value *) stmt->object),
821  newowner);
822 
824  return AlterEventTriggerOwner(strVal((Value *) stmt->object),
825  newowner);
826 
827  case OBJECT_PUBLICATION:
828  return AlterPublicationOwner(strVal((Value *) stmt->object),
829  newowner);
830 
831  case OBJECT_SUBSCRIPTION:
832  return AlterSubscriptionOwner(strVal((Value *) stmt->object),
833  newowner);
834 
835  /* Generic cases */
836  case OBJECT_AGGREGATE:
837  case OBJECT_COLLATION:
838  case OBJECT_CONVERSION:
839  case OBJECT_FUNCTION:
840  case OBJECT_LANGUAGE:
841  case OBJECT_LARGEOBJECT:
842  case OBJECT_OPERATOR:
843  case OBJECT_OPCLASS:
844  case OBJECT_OPFAMILY:
846  case OBJECT_TABLESPACE:
847  case OBJECT_TSDICTIONARY:
849  {
850  Relation catalog;
851  Relation relation;
852  Oid classId;
853  ObjectAddress address;
854 
855  address = get_object_address(stmt->objectType,
856  stmt->object,
857  &relation,
859  false);
860  Assert(relation == NULL);
861  classId = address.classId;
862 
863  /*
864  * XXX - get_object_address returns Oid of pg_largeobject
865  * catalog for OBJECT_LARGEOBJECT because of historical
866  * reasons. Fix up it here.
867  */
868  if (classId == LargeObjectRelationId)
870 
871  catalog = heap_open(classId, RowExclusiveLock);
872 
873  AlterObjectOwner_internal(catalog, address.objectId, newowner);
874  heap_close(catalog, RowExclusiveLock);
875 
876  return address;
877  }
878  break;
879 
880  default:
881  elog(ERROR, "unrecognized AlterOwnerStmt type: %d",
882  (int) stmt->objectType);
883  return InvalidObjectAddress; /* keep compiler happy */
884  }
885 }
RoleSpec * newowner
Definition: parsenodes.h:2834
#define castNode(_type_, nodeptr)
Definition: nodes.h:578
ObjectType objectType
Definition: parsenodes.h:2831
#define strVal(v)
Definition: value.h:54
#define heap_close(r, l)
Definition: heapam.h:97
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:3212
#define ERROR
Definition: elog.h:43
ObjectAddress AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
Definition: foreigncmds.c:277
void AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId)
Definition: alter.c:897
#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:5129
ObjectAddress AlterPublicationOwner(const char *name, Oid newOwnerId)
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define NULL
Definition: c.h:229
ObjectAddress AlterSchemaOwner(const char *name, Oid newOwnerId)
Definition: schemacmds.c:321
#define Assert(condition)
Definition: c.h:675
Definition: value.h:42
ObjectAddress AlterForeignServerOwner(const char *name, Oid newOwnerId)
Definition: foreigncmds.c:414
ObjectAddress get_object_address(ObjectType objtype, Node *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
#define LargeObjectMetadataRelationId
ObjectAddress AlterDatabaseOwner(const char *dbname, Oid newOwnerId)
Definition: dbcommands.c:1601
#define AccessExclusiveLock
Definition: lockdefs.h:45
const ObjectAddress InvalidObjectAddress
#define elog
Definition: elog.h:219
#define LargeObjectRelationId
Definition: pg_list.h:45
ObjectAddress ExecRenameStmt ( RenameStmt stmt)

Definition at line 325 of file alter.c.

References AccessExclusiveLock, AlterObjectRename_internal(), Assert, ObjectAddress::classId, elog, ERROR, get_object_address(), heap_close, heap_open(), InvalidObjectAddress, RenameStmt::newname, NULL, 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_PUBLICATION, OBJECT_ROLE, 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, and RenameStmt::subname.

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

326 {
327  switch (stmt->renameType)
328  {
331  return RenameConstraint(stmt);
332 
333  case OBJECT_DATABASE:
334  return RenameDatabase(stmt->subname, stmt->newname);
335 
336  case OBJECT_ROLE:
337  return RenameRole(stmt->subname, stmt->newname);
338 
339  case OBJECT_SCHEMA:
340  return RenameSchema(stmt->subname, stmt->newname);
341 
342  case OBJECT_TABLESPACE:
343  return RenameTableSpace(stmt->subname, stmt->newname);
344 
345  case OBJECT_TABLE:
346  case OBJECT_SEQUENCE:
347  case OBJECT_VIEW:
348  case OBJECT_MATVIEW:
349  case OBJECT_INDEX:
351  return RenameRelation(stmt);
352 
353  case OBJECT_COLUMN:
354  case OBJECT_ATTRIBUTE:
355  return renameatt(stmt);
356 
357  case OBJECT_RULE:
358  return RenameRewriteRule(stmt->relation, stmt->subname,
359  stmt->newname);
360 
361  case OBJECT_TRIGGER:
362  return renametrig(stmt);
363 
364  case OBJECT_POLICY:
365  return rename_policy(stmt);
366 
367  case OBJECT_DOMAIN:
368  case OBJECT_TYPE:
369  return RenameType(stmt);
370 
371  case OBJECT_AGGREGATE:
372  case OBJECT_COLLATION:
373  case OBJECT_CONVERSION:
375  case OBJECT_FDW:
377  case OBJECT_FUNCTION:
378  case OBJECT_OPCLASS:
379  case OBJECT_OPFAMILY:
380  case OBJECT_LANGUAGE:
383  case OBJECT_TSDICTIONARY:
384  case OBJECT_TSPARSER:
385  case OBJECT_TSTEMPLATE:
386  case OBJECT_PUBLICATION:
387  case OBJECT_SUBSCRIPTION:
388  {
389  ObjectAddress address;
390  Relation catalog;
391  Relation relation;
392 
393  address = get_object_address(stmt->renameType,
394  stmt->object,
395  &relation,
396  AccessExclusiveLock, false);
397  Assert(relation == NULL);
398 
399  catalog = heap_open(address.classId, RowExclusiveLock);
401  address.objectId,
402  stmt->newname);
403  heap_close(catalog, RowExclusiveLock);
404 
405  return address;
406  }
407 
408  default:
409  elog(ERROR, "unrecognized rename stmt type: %d",
410  (int) stmt->renameType);
411  return InvalidObjectAddress; /* keep compiler happy */
412  }
413 }
ObjectAddress RenameSchema(const char *oldname, const char *newname)
Definition: schemacmds.c:242
ObjectAddress RenameType(RenameStmt *stmt)
Definition: typecmds.c:3134
char * subname
Definition: parsenodes.h:2790
ObjectType renameType
Definition: parsenodes.h:2786
ObjectAddress RenameRelation(RenameStmt *stmt)
Definition: tablecmds.c:2870
#define heap_close(r, l)
Definition: heapam.h:97
char * newname
Definition: parsenodes.h:2792
ObjectAddress RenameDatabase(const char *oldname, const char *newname)
Definition: dbcommands.c:977
#define ERROR
Definition: elog.h:43
ObjectAddress rename_policy(RenameStmt *stmt)
Definition: policy.c:1202
#define RowExclusiveLock
Definition: lockdefs.h:38
Node * object
Definition: parsenodes.h:2789
ObjectAddress renametrig(RenameStmt *stmt)
Definition: trigger.c:1390
ObjectAddress renameatt(RenameStmt *stmt)
Definition: tablecmds.c:2682
ObjectAddress RenameConstraint(RenameStmt *stmt)
Definition: tablecmds.c:2819
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
RangeVar * relation
Definition: parsenodes.h:2788
ObjectAddress RenameRole(const char *oldname, const char *newname)
Definition: user.c:1108
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
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:166
ObjectAddress RenameRewriteRule(RangeVar *relation, const char *oldName, const char *newName)
ObjectAddress RenameTableSpace(const char *oldname, const char *newname)
Definition: tablespace.c:910
#define AccessExclusiveLock
Definition: lockdefs.h:45
const ObjectAddress InvalidObjectAddress
#define elog
Definition: elog.h:219
static void report_name_conflict ( Oid  classId,
const char *  name 
)
static

Definition at line 77 of file alter.c.

References elog, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, EventTriggerRelationId, ForeignDataWrapperRelationId, ForeignServerRelationId, gettext_noop, LanguageRelationId, PublicationRelationId, and SubscriptionRelationId.

Referenced by AlterObjectRename_internal().

78 {
79  char *msgfmt;
80 
81  switch (classId)
82  {
84  msgfmt = gettext_noop("event trigger \"%s\" already exists");
85  break;
87  msgfmt = gettext_noop("foreign-data wrapper \"%s\" already exists");
88  break;
90  msgfmt = gettext_noop("server \"%s\" already exists");
91  break;
92  case LanguageRelationId:
93  msgfmt = gettext_noop("language \"%s\" already exists");
94  break;
96  msgfmt = gettext_noop("publication \"%s\" already exists");
97  break;
99  msgfmt = gettext_noop("subscription \"%s\" already exists");
100  break;
101  default:
102  elog(ERROR, "unsupported object class %u", classId);
103  break;
104  }
105 
106  ereport(ERROR,
108  errmsg(msgfmt, name)));
109 }
#define gettext_noop(x)
Definition: c.h:139
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PublicationRelationId
#define ERROR
Definition: elog.h:43
#define SubscriptionRelationId
#define ereport(elevel, rest)
Definition: elog.h:122
#define ForeignServerRelationId
#define EventTriggerRelationId
#define ForeignDataWrapperRelationId
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define LanguageRelationId
Definition: pg_language.h:29
#define elog
Definition: elog.h:219
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:31
static void report_namespace_conflict ( Oid  classId,
const char *  name,
Oid  nspOid 
)
static

Definition at line 112 of file alter.c.

References Assert, ConversionRelationId, elog, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, get_namespace_name(), gettext_noop, OidIsValid, StatisticExtRelationId, TSConfigRelationId, TSDictionaryRelationId, TSParserRelationId, and TSTemplateRelationId.

Referenced by AlterObjectNamespace_internal(), and AlterObjectRename_internal().

113 {
114  char *msgfmt;
115 
116  Assert(OidIsValid(nspOid));
117 
118  switch (classId)
119  {
121  Assert(OidIsValid(nspOid));
122  msgfmt = gettext_noop("conversion \"%s\" already exists in schema \"%s\"");
123  break;
125  Assert(OidIsValid(nspOid));
126  msgfmt = gettext_noop("statistics object \"%s\" already exists in schema \"%s\"");
127  break;
128  case TSParserRelationId:
129  Assert(OidIsValid(nspOid));
130  msgfmt = gettext_noop("text search parser \"%s\" already exists in schema \"%s\"");
131  break;
133  Assert(OidIsValid(nspOid));
134  msgfmt = gettext_noop("text search dictionary \"%s\" already exists in schema \"%s\"");
135  break;
137  Assert(OidIsValid(nspOid));
138  msgfmt = gettext_noop("text search template \"%s\" already exists in schema \"%s\"");
139  break;
140  case TSConfigRelationId:
141  Assert(OidIsValid(nspOid));
142  msgfmt = gettext_noop("text search configuration \"%s\" already exists in schema \"%s\"");
143  break;
144  default:
145  elog(ERROR, "unsupported object class %u", classId);
146  break;
147  }
148 
149  ereport(ERROR,
151  errmsg(msgfmt, name, get_namespace_name(nspOid))));
152 }
#define gettext_noop(x)
Definition: c.h:139
int errcode(int sqlerrcode)
Definition: elog.c:575
#define OidIsValid(objectId)
Definition: c.h:538
#define TSConfigRelationId
Definition: pg_ts_config.h:31
#define ERROR
Definition: elog.h:43
#define TSDictionaryRelationId
Definition: pg_ts_dict.h:31
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3033
#define ereport(elevel, rest)
Definition: elog.h:122
#define TSParserRelationId
Definition: pg_ts_parser.h:31
#define Assert(condition)
Definition: c.h:675
#define StatisticExtRelationId
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:31
#define ConversionRelationId
Definition: pg_conversion.h:38
#define TSTemplateRelationId