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

Go to the source code of this file.

Functions

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

Function Documentation

◆ AlterObjectNamespace_internal()

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

Definition at line 688 of file alter.c.

689{
690 Oid classId = RelationGetRelid(rel);
697 Datum name,
698 namespace;
699 bool isnull;
701 newtup;
702 Datum *values;
703 bool *nulls;
704 bool *replaces;
705
707 if (!HeapTupleIsValid(tup)) /* should not happen */
708 elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
709 objid, RelationGetRelationName(rel));
710
712 Assert(!isnull);
714 &isnull);
715 Assert(!isnull);
716 oldNspOid = DatumGetObjectId(namespace);
717
718 /*
719 * If the object is already in the correct namespace, we don't need to do
720 * anything except fire the object access hook.
721 */
722 if (oldNspOid == nspOid)
723 {
724 InvokeObjectPostAlterHook(classId, objid, 0);
725 return oldNspOid;
726 }
727
728 /* Check basic namespace related issues */
730
731 /* Permission checks ... superusers can always do it */
732 if (!superuser())
733 {
734 Datum owner;
735 Oid ownerId;
737
738 /* Fail if object does not have an explicit owner */
739 if (Anum_owner <= 0)
742 errmsg("must be superuser to set schema of %s",
743 getObjectDescriptionOids(classId, objid))));
744
745 /* Otherwise, must be owner of the existing object */
746 owner = heap_getattr(tup, Anum_owner, RelationGetDescr(rel), &isnull);
747 Assert(!isnull);
748 ownerId = DatumGetObjectId(owner);
749
750 if (!has_privs_of_role(GetUserId(), ownerId))
753
754 /* User must have CREATE privilege on new namespace */
756 if (aclresult != ACLCHECK_OK)
759 }
760
761 /*
762 * Check for duplicate name (more friendly than unique-index failure).
763 * Since this is just a friendliness check, we can just skip it in cases
764 * where there isn't suitable support.
765 */
766 if (classId == ProcedureRelationId)
767 {
769
770 IsThereFunctionInNamespace(NameStr(proc->proname), proc->pronargs,
771 &proc->proargtypes, nspOid);
772 }
773 else if (classId == CollationRelationId)
774 {
776
778 }
779 else if (classId == OperatorClassRelationId)
780 {
782
784 opc->opcmethod, nspOid);
785 }
786 else if (classId == OperatorFamilyRelationId)
787 {
789
791 opf->opfmethod, nspOid);
792 }
793 else if (nameCacheId >= 0 &&
798 nspOid);
799
800 /* Build modified tuple */
802 nulls = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
803 replaces = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
805 replaces[Anum_namespace - 1] = true;
807 values, nulls, replaces);
808
809 /* Perform actual update */
810 CatalogTupleUpdate(rel, &tup->t_self, newtup);
811
812 /* Release memory */
813 pfree(values);
814 pfree(nulls);
816
817 /* update dependency to point to the new schema */
818 if (changeDependencyFor(classId, objid,
820 elog(ERROR, "could not change schema dependency for object %u",
821 objid);
822
823 InvokeObjectPostAlterHook(classId, objid, 0);
824
825 return oldNspOid;
826}
bool has_privs_of_role(Oid member, Oid role)
Definition acl.c:5314
AclResult
Definition acl.h:183
@ ACLCHECK_OK
Definition acl.h:184
@ ACLCHECK_NOT_OWNER
Definition acl.h:186
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition aclchk.c:2672
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition aclchk.c:3879
static void report_namespace_conflict(Oid classId, const char *name, Oid nspOid)
Definition alter.c:111
int16 AttrNumber
Definition attnum.h:21
static Datum values[MAXATTR]
Definition bootstrap.c:188
#define NameStr(name)
Definition c.h:837
#define Assert(condition)
Definition c.h:945
void IsThereCollationInNamespace(const char *collname, Oid nspOid)
int errcode(int sqlerrcode)
Definition elog.c:874
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
void IsThereFunctionInNamespace(const char *proname, int pronargs, oidvector *proargtypes, Oid nspOid)
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition heaptuple.c:1130
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
static void * GETSTRUCT(const HeapTupleData *tuple)
void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)
Definition indexing.c:313
char * get_namespace_name(Oid nspid)
Definition lsyscache.c:3588
void pfree(void *pointer)
Definition mcxt.c:1616
void * palloc0(Size size)
Definition mcxt.c:1417
Oid GetUserId(void)
Definition miscinit.c:470
void CheckSetNamespace(Oid oldNspOid, Oid nspOid)
Definition namespace.c:3531
static char * errmsg
#define InvokeObjectPostAlterHook(classId, objectId, subId)
AttrNumber get_object_attnum_owner(Oid class_id)
AttrNumber get_object_attnum_namespace(Oid class_id)
SysCacheIdentifier get_object_catcache_name(Oid class_id)
char * getObjectDescriptionOids(Oid classid, Oid objid)
AttrNumber get_object_attnum_name(Oid class_id)
SysCacheIdentifier 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)
void IsThereOpClassInNamespace(const char *opcname, Oid opcmethod, Oid opcnamespace)
@ OBJECT_SCHEMA
#define ACL_CREATE
Definition parsenodes.h:85
END_CATALOG_STRUCT typedef FormData_pg_collation * Form_pg_collation
long changeDependencyFor(Oid classId, Oid objectId, Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId)
Definition pg_depend.c:459
END_CATALOG_STRUCT typedef FormData_pg_opclass * Form_pg_opclass
Definition pg_opclass.h:87
END_CATALOG_STRUCT typedef FormData_pg_opfamily * Form_pg_opfamily
Definition pg_opfamily.h:55
END_CATALOG_STRUCT typedef FormData_pg_proc * Form_pg_proc
Definition pg_proc.h:140
static Name DatumGetName(Datum X)
Definition postgres.h:380
static Oid DatumGetObjectId(Datum X)
Definition postgres.h:242
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
uint64_t Datum
Definition postgres.h:70
unsigned int Oid
static int fb(int x)
#define RelationGetRelid(relation)
Definition rel.h:514
#define RelationGetDescr(relation)
Definition rel.h:540
#define RelationGetNumberOfAttributes(relation)
Definition rel.h:520
#define RelationGetRelationName(relation)
Definition rel.h:548
bool superuser(void)
Definition superuser.c:47
#define SearchSysCacheCopy1(cacheId, key1)
Definition syscache.h:91
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition syscache.h:102
const char * name

References ACL_CREATE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, Assert, CatalogTupleUpdate(), changeDependencyFor(), CheckSetNamespace(), DatumGetName(), DatumGetObjectId(), elog, ereport, errcode(), errmsg, ERROR, fb(), Form_pg_collation, Form_pg_opclass, Form_pg_opfamily, Form_pg_proc, 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(), and values.

Referenced by AlterObjectNamespace_oid(), and ExecAlterObjectSchemaStmt().

◆ AlterObjectNamespace_oid()

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

Definition at line 621 of file alter.c.

623{
625
626 switch (classId)
627 {
629 {
630 Relation rel;
631
634
636
638 break;
639 }
640
641 case TypeRelationId:
643 break;
644
656 {
658
660
662 nspOid);
663
665 }
666 break;
667
668 default:
669 /* ignore object types that don't have schema-qualified names */
671 }
672
673 return oldNspOid;
674}
static Oid AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
Definition alter.c:688
#define InvalidAttrNumber
Definition attnum.h:23
#define NoLock
Definition lockdefs.h:34
#define AccessExclusiveLock
Definition lockdefs.h:43
#define RowExclusiveLock
Definition lockdefs.h:38
#define InvalidOid
#define RelationGetNamespace(relation)
Definition rel.h:555
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)
Oid AlterTypeNamespace_oid(Oid typeOid, Oid nspOid, bool ignoreDependent, ObjectAddresses *objsMoved)
Definition typecmds.c:4145

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

Referenced by AlterExtensionNamespace().

◆ AlterObjectOwner_internal()

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

Definition at line 938 of file alter.c.

939{
940 /* For large objects, the catalog to modify is pg_largeobject_metadata */
941 Oid catalogId = (classId == LargeObjectRelationId) ? LargeObjectMetadataRelationId : classId;
947 Relation rel;
949 Datum datum;
950 bool isnull;
953
954 rel = table_open(catalogId, RowExclusiveLock);
955
956 /* Search tuple and lock it. */
957 oldtup =
958 get_catalog_object_by_oid_extended(rel, Anum_oid, objectId, true);
959 if (oldtup == NULL)
960 elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
961 objectId, RelationGetRelationName(rel));
962
964 RelationGetDescr(rel), &isnull);
965 Assert(!isnull);
967
969 {
971 RelationGetDescr(rel), &isnull);
972 Assert(!isnull);
974 }
975
977 {
978 AttrNumber nattrs;
980 Datum *values;
981 bool *nulls;
982 bool *replaces;
983
984 /* Superusers can bypass permission checks */
985 if (!superuser())
986 {
987 /* must be owner */
989 {
990 char *objname;
991 char namebuf[NAMEDATALEN];
992
994 {
996 RelationGetDescr(rel), &isnull);
997 Assert(!isnull);
998 objname = NameStr(*DatumGetName(datum));
999 }
1000 else
1001 {
1002 snprintf(namebuf, sizeof(namebuf), "%u", objectId);
1003 objname = namebuf;
1004 }
1006 get_object_type(catalogId, objectId),
1007 objname);
1008 }
1009 /* Must be able to become new owner */
1011
1012 /* New owner must have CREATE privilege on namespace */
1014 {
1016
1018 ACL_CREATE);
1019 if (aclresult != ACLCHECK_OK)
1022 }
1023 }
1024
1025 /* Build a modified tuple */
1026 nattrs = RelationGetNumberOfAttributes(rel);
1027 values = palloc0(nattrs * sizeof(Datum));
1028 nulls = palloc0(nattrs * sizeof(bool));
1029 replaces = palloc0(nattrs * sizeof(bool));
1031 replaces[Anum_owner - 1] = true;
1032
1033 /*
1034 * Determine the modified ACL for the new owner. This is only
1035 * necessary when the ACL is non-null.
1036 */
1038 {
1039 datum = heap_getattr(oldtup,
1040 Anum_acl, RelationGetDescr(rel), &isnull);
1041 if (!isnull)
1042 {
1043 Acl *newAcl;
1044
1048 replaces[Anum_acl - 1] = true;
1049 }
1050 }
1051
1053 values, nulls, replaces);
1054
1055 /* Perform actual update */
1056 CatalogTupleUpdate(rel, &newtup->t_self, newtup);
1057
1059
1060 /* Update owner dependency reference */
1061 changeDependencyOnOwner(classId, objectId, new_ownerId);
1062
1063 /* Release memory */
1064 pfree(values);
1065 pfree(nulls);
1066 pfree(replaces);
1067 }
1068 else
1070
1071 /* Note the post-alter hook gets classId not catalogId */
1072 InvokeObjectPostAlterHook(classId, objectId, 0);
1073
1075}
Acl * aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
Definition acl.c:1147
void check_can_set_role(Oid member, Oid role)
Definition acl.c:5371
#define DatumGetAclP(X)
Definition acl.h:120
#define OidIsValid(objectId)
Definition c.h:860
void UnlockTuple(Relation relation, const ItemPointerData *tid, LOCKMODE lockmode)
Definition lmgr.c:601
#define InplaceUpdateTupleLock
Definition lockdefs.h:48
AttrNumber get_object_attnum_oid(Oid class_id)
AttrNumber get_object_attnum_acl(Oid class_id)
HeapTuple get_catalog_object_by_oid_extended(Relation catalog, AttrNumber oidcol, Oid objectId, bool locktup)
#define NAMEDATALEN
void changeDependencyOnOwner(Oid classId, Oid objectId, Oid newOwnerId)
#define snprintf
Definition port.h:260
static Datum PointerGetDatum(const void *X)
Definition postgres.h:342

References ACL_CREATE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, aclnewowner(), Assert, CatalogTupleUpdate(), changeDependencyOnOwner(), check_can_set_role(), DatumGetAclP, DatumGetName(), DatumGetObjectId(), elog, ERROR, fb(), get_catalog_object_by_oid_extended(), 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(), InplaceUpdateTupleLock, InvalidAttrNumber, InvalidOid, InvokeObjectPostAlterHook, NAMEDATALEN, NameStr, object_aclcheck(), OBJECT_SCHEMA, ObjectIdGetDatum(), OidIsValid, palloc0(), pfree(), PointerGetDatum(), RelationGetDescr, RelationGetNumberOfAttributes, RelationGetRelationName, RowExclusiveLock, snprintf, superuser(), table_close(), table_open(), UnlockTuple(), and values.

Referenced by ExecAlterOwnerStmt(), and shdepReassignOwned_Owner().

◆ AlterObjectRename_internal()

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

Definition at line 159 of file alter.c.

160{
161 Oid classId = RelationGetRelid(rel);
169 Datum datum;
170 bool isnull;
172 Oid ownerId;
173 char *old_name;
175 Datum *values;
176 bool *nulls;
177 bool *replaces;
179
182 elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
183 objectId, RelationGetRelationName(rel));
184
186 RelationGetDescr(rel), &isnull);
187 Assert(!isnull);
188 old_name = NameStr(*(DatumGetName(datum)));
189
190 /* Get OID of namespace */
191 if (Anum_namespace > 0)
192 {
194 RelationGetDescr(rel), &isnull);
195 Assert(!isnull);
197 }
198 else
200
201 /* Permission checks ... superusers can always do it */
202 if (!superuser())
203 {
204 /* Fail if object does not have an explicit owner */
205 if (Anum_owner <= 0)
208 errmsg("must be superuser to rename %s",
209 getObjectDescriptionOids(classId, objectId))));
210
211 /* Otherwise, must be owner of the existing object */
213 RelationGetDescr(rel), &isnull);
214 Assert(!isnull);
215 ownerId = DatumGetObjectId(datum);
216
217 if (!has_privs_of_role(GetUserId(), ownerId))
219 old_name);
220
221 /* User must have CREATE privilege on the namespace */
223 {
225 ACL_CREATE);
226 if (aclresult != ACLCHECK_OK)
229 }
230
231 if (classId == SubscriptionRelationId)
232 {
234
235 /* must have CREATE privilege on database */
238 if (aclresult != ACLCHECK_OK)
241
242 /*
243 * Don't allow non-superuser modification of a subscription with
244 * password_required=false.
245 */
247 if (!form->subpasswordrequired && !superuser())
250 errmsg("password_required=false is superuser-only"),
251 errhint("Subscriptions with the password_required option set to false may only be created or modified by the superuser.")));
252 }
253 }
254
255 /*
256 * Check for duplicate name (more friendly than unique-index failure).
257 * Since this is just a friendliness check, we can just skip it in cases
258 * where there isn't suitable support.
259 */
260 if (classId == ProcedureRelationId)
261 {
263
264 IsThereFunctionInNamespace(new_name, proc->pronargs,
265 &proc->proargtypes, proc->pronamespace);
266 }
267 else if (classId == CollationRelationId)
268 {
270
272 }
273 else if (classId == OperatorClassRelationId)
274 {
276
278 opc->opcnamespace);
279 }
280 else if (classId == OperatorFamilyRelationId)
281 {
283
285 opf->opfnamespace);
286 }
287 else if (classId == SubscriptionRelationId)
288 {
293
294 /* Also enforce regression testing naming rules, if enabled */
295#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS
296 if (strncmp(new_name, "regress_", 8) != 0)
297 elog(WARNING, "subscriptions created by regression test cases should have names starting with \"regress_\"");
298#endif
299
300 /* Wake up related replication workers to handle this change quickly */
302 }
303 else if (nameCacheId >= 0)
304 {
306 {
311 }
312 else
313 {
317 }
318 }
319
320 /* Build modified tuple */
322 nulls = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
323 replaces = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
326 replaces[Anum_name - 1] = true;
328 values, nulls, replaces);
329
330 /* Perform actual update */
331 CatalogTupleUpdate(rel, &oldtup->t_self, newtup);
332
333 InvokeObjectPostAlterHook(classId, objectId, 0);
334
335 /* Do post catalog-update tasks */
336 if (classId == PublicationRelationId)
337 {
339
340 /*
341 * Invalidate relsynccache entries.
342 *
343 * Unlike ALTER PUBLICATION ADD/SET/DROP commands, renaming a
344 * publication does not impact the publication status of tables. So,
345 * we don't need to invalidate relcache to rebuild the rd_pubdesc.
346 * Instead, we invalidate only the relsyncache.
347 */
348 InvalidatePubRelSyncCache(pub->oid, pub->puballtables);
349 }
350
351 /* Release memory */
352 pfree(values);
353 pfree(nulls);
356
358}
static void report_name_conflict(Oid classId, const char *name)
Definition alter.c:76
void LogicalRepWorkersWakeupAtCommit(Oid subid)
Definition worker.c:6317
int errhint(const char *fmt,...) pg_attribute_printf(1
#define WARNING
Definition elog.h:36
Oid MyDatabaseId
Definition globals.c:94
void heap_freetuple(HeapTuple htup)
Definition heaptuple.c:1384
char * get_database_name(Oid dbid)
Definition lsyscache.c:1312
void namestrcpy(Name name, const char *str)
Definition name.c:233
@ OBJECT_DATABASE
END_CATALOG_STRUCT typedef FormData_pg_publication * Form_pg_publication
END_CATALOG_STRUCT typedef FormData_pg_subscription * Form_pg_subscription
static Datum NameGetDatum(const NameData *X)
Definition postgres.h:393
static Datum CStringGetDatum(const char *X)
Definition postgres.h:370
void InvalidatePubRelSyncCache(Oid pubid, bool puballtables)
Definition c.h:832
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:265
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:221
#define SearchSysCacheExists1(cacheId, key1)
Definition syscache.h:100

References ACL_CREATE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, Assert, CatalogTupleUpdate(), CStringGetDatum(), DatumGetName(), DatumGetObjectId(), elog, ereport, errcode(), errhint(), errmsg, ERROR, fb(), Form_pg_collation, Form_pg_opclass, Form_pg_opfamily, Form_pg_proc, Form_pg_publication, Form_pg_subscription, 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, InvalidatePubRelSyncCache(), InvalidOid, InvokeObjectPostAlterHook, IsThereCollationInNamespace(), IsThereFunctionInNamespace(), IsThereOpClassInNamespace(), IsThereOpFamilyInNamespace(), LogicalRepWorkersWakeupAtCommit(), MyDatabaseId, NameGetDatum(), NameStr, namestrcpy(), object_aclcheck(), OBJECT_DATABASE, OBJECT_SCHEMA, ObjectIdGetDatum(), OidIsValid, palloc0(), pfree(), RelationGetDescr, RelationGetNumberOfAttributes, RelationGetRelationName, RelationGetRelid, ReleaseSysCache(), report_name_conflict(), report_namespace_conflict(), SearchSysCache1(), SearchSysCacheExists1, SearchSysCacheExists2, superuser(), values, and WARNING.

Referenced by ExecRenameStmt().

◆ ExecAlterObjectDependsStmt()

ObjectAddress ExecAlterObjectDependsStmt ( AlterObjectDependsStmt stmt,
ObjectAddress refAddress 
)

Definition at line 466 of file alter.c.

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

References AccessExclusiveLock, check_object_ownership(), ObjectAddress::classId, deleteDependencyRecordsForSpecific(), DEPENDENCY_AUTO_EXTENSION, fb(), 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 529 of file alter.c.

531{
532 ObjectAddress address;
534
535 switch (stmt->objectType)
536 {
537 case OBJECT_EXTENSION:
538 address = AlterExtensionNamespace(strVal(stmt->object), stmt->newschema,
540 break;
541
543 case OBJECT_SEQUENCE:
544 case OBJECT_TABLE:
545 case OBJECT_VIEW:
546 case OBJECT_MATVIEW:
547 case OBJECT_PROPGRAPH:
548 address = AlterTableNamespace(stmt,
550 break;
551
552 case OBJECT_DOMAIN:
553 case OBJECT_TYPE:
554 address = AlterTypeNamespace(castNode(List, stmt->object), stmt->newschema,
555 stmt->objectType,
557 break;
558
559 /* generic code path */
560 case OBJECT_AGGREGATE:
561 case OBJECT_COLLATION:
563 case OBJECT_FUNCTION:
564 case OBJECT_OPERATOR:
565 case OBJECT_OPCLASS:
566 case OBJECT_OPFAMILY:
567 case OBJECT_PROCEDURE:
568 case OBJECT_ROUTINE:
572 case OBJECT_TSPARSER:
574 {
576 Oid classId;
577 Oid nspOid;
578
579 address = get_object_address(stmt->objectType,
580 stmt->object,
581 NULL,
583 false);
584 classId = address.classId;
586 nspOid = LookupCreationNamespace(stmt->newschema);
587
589 nspOid);
591 }
592 break;
593
594 default:
595 elog(ERROR, "unrecognized AlterObjectSchemaStmt type: %d",
596 (int) stmt->objectType);
597 return InvalidObjectAddress; /* keep compiler happy */
598 }
599
600 if (oldSchemaAddr)
602
603 return address;
604}
ObjectAddress AlterExtensionNamespace(const char *extensionName, const char *newschema, Oid *oldschema)
Definition extension.c:3253
Oid LookupCreationNamespace(const char *nspname)
Definition namespace.c:3500
#define castNode(_type_, nodeptr)
Definition nodes.h:182
const ObjectAddress InvalidObjectAddress
#define ObjectAddressSet(addr, class_id, object_id)
@ OBJECT_TSPARSER
@ OBJECT_COLLATION
@ OBJECT_PROPGRAPH
@ OBJECT_OPCLASS
@ OBJECT_AGGREGATE
@ OBJECT_MATVIEW
@ OBJECT_OPERATOR
@ OBJECT_FOREIGN_TABLE
@ OBJECT_TSCONFIGURATION
@ OBJECT_OPFAMILY
@ OBJECT_DOMAIN
@ OBJECT_ROUTINE
@ OBJECT_PROCEDURE
@ OBJECT_SEQUENCE
@ OBJECT_TSTEMPLATE
@ OBJECT_TSDICTIONARY
@ OBJECT_CONVERSION
@ OBJECT_TABLE
@ OBJECT_VIEW
@ OBJECT_TYPE
@ OBJECT_FUNCTION
@ OBJECT_STATISTIC_EXT
ObjectAddress AlterTableNamespace(AlterObjectSchemaStmt *stmt, Oid *oldschema)
ObjectAddress AlterTypeNamespace(List *names, const char *newschema, ObjectType objecttype, Oid *oldschema)
Definition typecmds.c:4096
#define strVal(v)
Definition value.h:82

References AccessExclusiveLock, AlterExtensionNamespace(), AlterObjectNamespace_internal(), AlterTableNamespace(), AlterTypeNamespace(), castNode, ObjectAddress::classId, elog, ERROR, fb(), 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_PROPGRAPH, 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 833 of file alter.c.

834{
835 Oid newowner = get_rolespec_oid(stmt->newowner, false);
836
837 switch (stmt->objectType)
838 {
839 case OBJECT_DATABASE:
840 return AlterDatabaseOwner(strVal(stmt->object), newowner);
841
842 case OBJECT_SCHEMA:
843 return AlterSchemaOwner(strVal(stmt->object), newowner);
844
845 case OBJECT_TYPE:
846 case OBJECT_DOMAIN: /* same as TYPE */
847 return AlterTypeOwner(castNode(List, stmt->object), newowner, stmt->objectType);
848 break;
849
850 case OBJECT_FDW:
852 newowner);
853
855 return AlterForeignServerOwner(strVal(stmt->object),
856 newowner);
857
859 return AlterEventTriggerOwner(strVal(stmt->object),
860 newowner);
861
863 return AlterPublicationOwner(strVal(stmt->object),
864 newowner);
865
867 return AlterSubscriptionOwner(strVal(stmt->object),
868 newowner);
869
870 /* Generic cases */
871 case OBJECT_AGGREGATE:
872 case OBJECT_COLLATION:
874 case OBJECT_FUNCTION:
875 case OBJECT_LANGUAGE:
877 case OBJECT_OPERATOR:
878 case OBJECT_OPCLASS:
879 case OBJECT_OPFAMILY:
880 case OBJECT_PROCEDURE:
881 case OBJECT_PROPGRAPH:
882 case OBJECT_ROUTINE:
887 {
888 ObjectAddress address;
889
890 if (stmt->relation)
891 {
892 Relation relation;
893
894 address = get_object_address_rv(stmt->objectType,
895 stmt->relation,
896 NIL,
897 &relation,
899 false);
900 relation_close(relation, NoLock);
901 }
902 else
903 {
904 address = get_object_address(stmt->objectType,
905 stmt->object,
906 NULL,
908 false);
909 }
910
912 newowner);
913
914 return address;
915 }
916 break;
917
918 default:
919 elog(ERROR, "unrecognized AlterOwnerStmt type: %d",
920 (int) stmt->objectType);
921 return InvalidObjectAddress; /* keep compiler happy */
922 }
923}
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition acl.c:5639
void AlterObjectOwner_internal(Oid classId, Oid objectId, Oid new_ownerId)
Definition alter.c:938
ObjectAddress AlterDatabaseOwner(const char *dbname, Oid newOwnerId)
ObjectAddress AlterEventTriggerOwner(const char *name, Oid newOwnerId)
ObjectAddress AlterForeignServerOwner(const char *name, Oid newOwnerId)
ObjectAddress AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
@ OBJECT_EVENT_TRIGGER
@ OBJECT_FDW
@ OBJECT_TABLESPACE
@ OBJECT_LARGEOBJECT
@ OBJECT_LANGUAGE
@ OBJECT_FOREIGN_SERVER
@ OBJECT_PUBLICATION
@ OBJECT_SUBSCRIPTION
#define NIL
Definition pg_list.h:68
ObjectAddress AlterPublicationOwner(const char *name, Oid newOwnerId)
ObjectAddress AlterSchemaOwner(const char *name, Oid newOwnerId)
Definition schemacmds.c:331
ObjectAddress AlterSubscriptionOwner(const char *name, Oid newOwnerId)
ObjectAddress AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype)
Definition typecmds.c:3863

References AccessExclusiveLock, AlterDatabaseOwner(), AlterEventTriggerOwner(), AlterForeignDataWrapperOwner(), AlterForeignServerOwner(), AlterObjectOwner_internal(), AlterPublicationOwner(), AlterSchemaOwner(), AlterSubscriptionOwner(), AlterTypeOwner(), castNode, ObjectAddress::classId, elog, ERROR, fb(), get_object_address(), get_object_address_rv(), get_rolespec_oid(), InvalidObjectAddress, NIL, NoLock, 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_PROPGRAPH, OBJECT_PUBLICATION, OBJECT_ROUTINE, OBJECT_SCHEMA, OBJECT_STATISTIC_EXT, OBJECT_SUBSCRIPTION, OBJECT_TABLESPACE, OBJECT_TSCONFIGURATION, OBJECT_TSDICTIONARY, OBJECT_TYPE, ObjectAddress::objectId, relation_close(), stmt, and strVal.

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

◆ ExecRenameStmt()

ObjectAddress ExecRenameStmt ( RenameStmt stmt)

Definition at line 367 of file alter.c.

368{
369 switch (stmt->renameType)
370 {
373 return RenameConstraint(stmt);
374
375 case OBJECT_DATABASE:
376 return RenameDatabase(stmt->subname, stmt->newname);
377
378 case OBJECT_ROLE:
379 return RenameRole(stmt->subname, stmt->newname);
380
381 case OBJECT_SCHEMA:
382 return RenameSchema(stmt->subname, stmt->newname);
383
385 return RenameTableSpace(stmt->subname, stmt->newname);
386
387 case OBJECT_TABLE:
388 case OBJECT_SEQUENCE:
389 case OBJECT_VIEW:
390 case OBJECT_MATVIEW:
391 case OBJECT_INDEX:
393 case OBJECT_PROPGRAPH:
394 return RenameRelation(stmt);
395
396 case OBJECT_COLUMN:
397 case OBJECT_ATTRIBUTE:
398 return renameatt(stmt);
399
400 case OBJECT_RULE:
401 return RenameRewriteRule(stmt->relation, stmt->subname,
402 stmt->newname);
403
404 case OBJECT_TRIGGER:
405 return renametrig(stmt);
406
407 case OBJECT_POLICY:
408 return rename_policy(stmt);
409
410 case OBJECT_DOMAIN:
411 case OBJECT_TYPE:
412 return RenameType(stmt);
413
414 case OBJECT_AGGREGATE:
415 case OBJECT_COLLATION:
418 case OBJECT_FDW:
420 case OBJECT_FUNCTION:
421 case OBJECT_OPCLASS:
422 case OBJECT_OPFAMILY:
423 case OBJECT_LANGUAGE:
424 case OBJECT_PROCEDURE:
425 case OBJECT_ROUTINE:
429 case OBJECT_TSPARSER:
433 {
434 ObjectAddress address;
436
437 address = get_object_address(stmt->renameType,
438 stmt->object,
439 NULL,
440 AccessExclusiveLock, false);
441
444 address.objectId,
445 stmt->newname);
447
448 return address;
449 }
450
451 default:
452 elog(ERROR, "unrecognized rename stmt type: %d",
453 (int) stmt->renameType);
454 return InvalidObjectAddress; /* keep compiler happy */
455 }
456}
static void AlterObjectRename_internal(Relation rel, Oid objectId, const char *new_name)
Definition alter.c:159
ObjectAddress RenameTableSpace(const char *oldname, const char *newname)
Definition tablespace.c:938
ObjectAddress RenameDatabase(const char *oldname, const char *newname)
@ OBJECT_POLICY
@ OBJECT_COLUMN
@ OBJECT_ROLE
@ OBJECT_INDEX
@ OBJECT_ATTRIBUTE
@ OBJECT_RULE
@ OBJECT_TABCONSTRAINT
@ OBJECT_DOMCONSTRAINT
@ OBJECT_TRIGGER
ObjectAddress rename_policy(RenameStmt *stmt)
Definition policy.c:1096
ObjectAddress RenameRewriteRule(RangeVar *relation, const char *oldName, const char *newName)
ObjectAddress RenameSchema(const char *oldname, const char *newname)
Definition schemacmds.c:250
ObjectAddress RenameRelation(RenameStmt *stmt)
Definition tablecmds.c:4237
ObjectAddress renameatt(RenameStmt *stmt)
Definition tablecmds.c:4040
ObjectAddress RenameConstraint(RenameStmt *stmt)
Definition tablecmds.c:4187
ObjectAddress renametrig(RenameStmt *stmt)
Definition trigger.c:1469
ObjectAddress RenameType(RenameStmt *stmt)
Definition typecmds.c:3782
ObjectAddress RenameRole(const char *oldname, const char *newname)
Definition user.c:1341

References AccessExclusiveLock, AlterObjectRename_internal(), ObjectAddress::classId, elog, ERROR, fb(), 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_PROPGRAPH, 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 76 of file alter.c.

77{
78 char *msgfmt;
79
80 switch (classId)
81 {
83 msgfmt = gettext_noop("event trigger \"%s\" already exists");
84 break;
86 msgfmt = gettext_noop("foreign-data wrapper \"%s\" already exists");
87 break;
89 msgfmt = gettext_noop("server \"%s\" already exists");
90 break;
92 msgfmt = gettext_noop("language \"%s\" already exists");
93 break;
95 msgfmt = gettext_noop("publication \"%s\" already exists");
96 break;
98 msgfmt = gettext_noop("subscription \"%s\" already exists");
99 break;
100 default:
101 elog(ERROR, "unsupported object class: %u", classId);
102 break;
103 }
104
107 errmsg(msgfmt, name)));
108}
#define gettext_noop(x)
Definition c.h:1287
#define ERRCODE_DUPLICATE_OBJECT
Definition streamutil.c:30

References elog, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg, ERROR, fb(), 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 111 of file alter.c.

112{
113 char *msgfmt;
114
116
117 switch (classId)
118 {
120 msgfmt = gettext_noop("conversion \"%s\" already exists in schema \"%s\"");
121 break;
123 msgfmt = gettext_noop("statistics object \"%s\" already exists in schema \"%s\"");
124 break;
126 msgfmt = gettext_noop("text search parser \"%s\" already exists in schema \"%s\"");
127 break;
129 msgfmt = gettext_noop("text search dictionary \"%s\" already exists in schema \"%s\"");
130 break;
132 msgfmt = gettext_noop("text search template \"%s\" already exists in schema \"%s\"");
133 break;
135 msgfmt = gettext_noop("text search configuration \"%s\" already exists in schema \"%s\"");
136 break;
137 default:
138 elog(ERROR, "unsupported object class: %u", classId);
139 break;
140 }
141
145}

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

Referenced by AlterObjectNamespace_internal(), and AlterObjectRename_internal().