#include "catalog/dependency.h"
#include "nodes/parsenodes.h"
#include "utils/relcache.h"
Go to the source code of this file.
Functions | |
Oid | ExecRenameStmt (RenameStmt *stmt) |
Oid | ExecAlterObjectSchemaStmt (AlterObjectSchemaStmt *stmt) |
Oid | AlterObjectNamespace_oid (Oid classId, Oid objid, Oid nspOid, ObjectAddresses *objsMoved) |
Oid | ExecAlterOwnerStmt (AlterOwnerStmt *stmt) |
void | AlterObjectOwner_internal (Relation catalog, Oid objectId, Oid new_ownerId) |
Oid AlterObjectNamespace_oid | ( | Oid | classId, | |
Oid | objid, | |||
Oid | nspOid, | |||
ObjectAddresses * | objsMoved | |||
) |
Definition at line 468 of file alter.c.
References AccessExclusiveLock, AlterObjectNamespace_internal(), AlterTableNamespaceInternal(), AlterTypeNamespace_oid(), ObjectAddress::classId, getObjectClass(), heap_close, heap_open(), NoLock, ObjectAddress::objectId, ObjectAddress::objectSubId, OCLASS_CLASS, OCLASS_COLLATION, OCLASS_CONVERSION, OCLASS_OPCLASS, OCLASS_OPERATOR, OCLASS_OPFAMILY, OCLASS_PROC, OCLASS_TSCONFIG, OCLASS_TSDICT, OCLASS_TSPARSER, OCLASS_TSTEMPLATE, OCLASS_TYPE, relation_close(), relation_open(), RelationGetNamespace, and RowExclusiveLock.
Referenced by AlterExtensionNamespace().
{ Oid oldNspOid = InvalidOid; ObjectAddress dep; dep.classId = classId; dep.objectId = objid; dep.objectSubId = 0; switch (getObjectClass(&dep)) { case OCLASS_CLASS: { Relation rel; rel = relation_open(objid, AccessExclusiveLock); oldNspOid = RelationGetNamespace(rel); AlterTableNamespaceInternal(rel, oldNspOid, nspOid, objsMoved); relation_close(rel, NoLock); break; } case OCLASS_TYPE: oldNspOid = AlterTypeNamespace_oid(objid, nspOid, objsMoved); break; case OCLASS_COLLATION: case OCLASS_CONVERSION: case OCLASS_OPERATOR: case OCLASS_OPCLASS: case OCLASS_OPFAMILY: case OCLASS_PROC: case OCLASS_TSPARSER: case OCLASS_TSDICT: case OCLASS_TSTEMPLATE: case OCLASS_TSCONFIG: { Relation catalog; catalog = heap_open(classId, RowExclusiveLock); oldNspOid = AlterObjectNamespace_internal(catalog, objid, nspOid); heap_close(catalog, RowExclusiveLock); } break; default: break; } return oldNspOid; }
Definition at line 765 of file alter.c.
References ACL_CREATE, ACL_KIND_NAMESPACE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, aclnewowner(), Assert, CatalogUpdateIndexes(), 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, InvokeObjectPostAlterHook, LargeObjectMetadataRelationId, NameStr, NULL, ObjectIdGetDatum, OidIsValid, palloc0(), pfree(), pg_namespace_aclcheck(), PointerGetDatum, RelationGetDescr, RelationGetNumberOfAttributes, RelationGetRelationName, RelationGetRelid, simple_heap_update(), snprintf(), superuser(), HeapTupleData::t_self, and values.
Referenced by ExecAlterOwnerStmt(), and shdepReassignOwned().
{ Oid classId = RelationGetRelid(rel); AttrNumber Anum_owner = get_object_attnum_owner(classId); AttrNumber Anum_namespace = get_object_attnum_namespace(classId); AttrNumber Anum_acl = get_object_attnum_acl(classId); AttrNumber Anum_name = get_object_attnum_name(classId); HeapTuple oldtup; Datum datum; bool isnull; Oid old_ownerId; Oid namespaceId = InvalidOid; oldtup = get_catalog_object_by_oid(rel, objectId); if (oldtup == NULL) elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"", objectId, RelationGetRelationName(rel)); datum = heap_getattr(oldtup, Anum_owner, RelationGetDescr(rel), &isnull); Assert(!isnull); old_ownerId = DatumGetObjectId(datum); if (Anum_namespace != InvalidAttrNumber) { datum = heap_getattr(oldtup, Anum_namespace, RelationGetDescr(rel), &isnull); Assert(!isnull); namespaceId = DatumGetObjectId(datum); } if (old_ownerId != new_ownerId) { AttrNumber nattrs; HeapTuple newtup; Datum *values; bool *nulls; bool *replaces; /* Superusers can bypass permission checks */ if (!superuser()) { AclObjectKind aclkind = get_object_aclkind(classId); /* must be owner */ if (!has_privs_of_role(GetUserId(), old_ownerId)) { char *objname; char namebuf[NAMEDATALEN]; if (Anum_name != InvalidAttrNumber) { datum = heap_getattr(oldtup, Anum_name, RelationGetDescr(rel), &isnull); Assert(!isnull); objname = NameStr(*DatumGetName(datum)); } else { snprintf(namebuf, sizeof(namebuf), "%u", HeapTupleGetOid(oldtup)); objname = namebuf; } aclcheck_error(ACLCHECK_NOT_OWNER, aclkind, objname); } /* Must be able to become new owner */ check_is_member_of_role(GetUserId(), new_ownerId); /* New owner must have CREATE privilege on namespace */ if (OidIsValid(namespaceId)) { AclResult aclresult; aclresult = pg_namespace_aclcheck(namespaceId, new_ownerId, ACL_CREATE); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_NAMESPACE, get_namespace_name(namespaceId)); } } /* Build a modified tuple */ nattrs = RelationGetNumberOfAttributes(rel); values = palloc0(nattrs * sizeof(Datum)); nulls = palloc0(nattrs * sizeof(bool)); replaces = palloc0(nattrs * sizeof(bool)); values[Anum_owner - 1] = ObjectIdGetDatum(new_ownerId); replaces[Anum_owner - 1] = true; /* * Determine the modified ACL for the new owner. This is only * necessary when the ACL is non-null. */ if (Anum_acl != InvalidAttrNumber) { datum = heap_getattr(oldtup, Anum_acl, RelationGetDescr(rel), &isnull); if (!isnull) { Acl *newAcl; newAcl = aclnewowner(DatumGetAclP(datum), old_ownerId, new_ownerId); values[Anum_acl - 1] = PointerGetDatum(newAcl); replaces[Anum_acl - 1] = true; } } newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel), values, nulls, replaces); /* Perform actual update */ simple_heap_update(rel, &newtup->t_self, newtup); CatalogUpdateIndexes(rel, newtup); /* Update owner dependency reference */ if (classId == LargeObjectMetadataRelationId) classId = LargeObjectRelationId; changeDependencyOnOwner(classId, HeapTupleGetOid(newtup), new_ownerId); /* Release memory */ pfree(values); pfree(nulls); pfree(replaces); } InvokeObjectPostAlterHook(classId, objectId, 0); }
Oid ExecAlterObjectSchemaStmt | ( | AlterObjectSchemaStmt * | stmt | ) |
Definition at line 389 of file alter.c.
References AccessExclusiveLock, AlterExtensionNamespace(), AlterObjectNamespace_internal(), AlterTableNamespace(), AlterTypeNamespace(), Assert, ObjectAddress::classId, elog, ERROR, get_object_address(), heap_close, heap_open(), LookupCreationNamespace(), AlterObjectSchemaStmt::newschema, NULL, AlterObjectSchemaStmt::objarg, 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_TABLE, OBJECT_TSCONFIGURATION, OBJECT_TSDICTIONARY, OBJECT_TSPARSER, OBJECT_TSTEMPLATE, OBJECT_TYPE, OBJECT_VIEW, ObjectAddress::objectId, AlterObjectSchemaStmt::objectType, and RowExclusiveLock.
Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().
{ switch (stmt->objectType) { case OBJECT_EXTENSION: return AlterExtensionNamespace(stmt->object, stmt->newschema); case OBJECT_FOREIGN_TABLE: case OBJECT_SEQUENCE: case OBJECT_TABLE: case OBJECT_VIEW: case OBJECT_MATVIEW: return AlterTableNamespace(stmt); case OBJECT_DOMAIN: case OBJECT_TYPE: return AlterTypeNamespace(stmt->object, stmt->newschema, stmt->objectType); /* generic code path */ case OBJECT_AGGREGATE: case OBJECT_COLLATION: case OBJECT_CONVERSION: case OBJECT_FUNCTION: case OBJECT_OPERATOR: case OBJECT_OPCLASS: case OBJECT_OPFAMILY: case OBJECT_TSCONFIGURATION: case OBJECT_TSDICTIONARY: case OBJECT_TSPARSER: case OBJECT_TSTEMPLATE: { Relation catalog; Relation relation; Oid classId; Oid nspOid; ObjectAddress address; address = get_object_address(stmt->objectType, stmt->object, stmt->objarg, &relation, AccessExclusiveLock, false); Assert(relation == NULL); classId = address.classId; catalog = heap_open(classId, RowExclusiveLock); nspOid = LookupCreationNamespace(stmt->newschema); AlterObjectNamespace_internal(catalog, address.objectId, nspOid); heap_close(catalog, RowExclusiveLock); return address.objectId; } break; default: elog(ERROR, "unrecognized AlterObjectSchemaStmt type: %d", (int) stmt->objectType); return InvalidOid; /* keep compiler happy */ } }
Oid ExecAlterOwnerStmt | ( | AlterOwnerStmt * | stmt | ) |
Definition at line 673 of file alter.c.
References AccessExclusiveLock, AlterDatabaseOwner(), AlterEventTriggerOwner(), AlterForeignDataWrapperOwner(), AlterForeignServerOwner(), AlterObjectOwner_internal(), AlterSchemaOwner(), AlterTypeOwner(), Assert, ObjectAddress::classId, elog, ERROR, get_object_address(), get_role_oid(), heap_close, heap_open(), LargeObjectRelationId, linitial, AlterOwnerStmt::newowner, NULL, AlterOwnerStmt::objarg, 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_SCHEMA, OBJECT_TABLESPACE, OBJECT_TSCONFIGURATION, OBJECT_TSDICTIONARY, OBJECT_TYPE, ObjectAddress::objectId, AlterOwnerStmt::objectType, RowExclusiveLock, and strVal.
Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().
{ Oid newowner = get_role_oid(stmt->newowner, false); switch (stmt->objectType) { case OBJECT_DATABASE: return AlterDatabaseOwner(strVal(linitial(stmt->object)), newowner); case OBJECT_SCHEMA: return AlterSchemaOwner(strVal(linitial(stmt->object)), newowner); case OBJECT_TYPE: case OBJECT_DOMAIN: /* same as TYPE */ return AlterTypeOwner(stmt->object, newowner, stmt->objectType); break; case OBJECT_FDW: return AlterForeignDataWrapperOwner(strVal(linitial(stmt->object)), newowner); case OBJECT_FOREIGN_SERVER: return AlterForeignServerOwner(strVal(linitial(stmt->object)), newowner); case OBJECT_EVENT_TRIGGER: return AlterEventTriggerOwner(strVal(linitial(stmt->object)), newowner); /* Generic cases */ case OBJECT_AGGREGATE: case OBJECT_COLLATION: case OBJECT_CONVERSION: case OBJECT_FUNCTION: case OBJECT_LANGUAGE: case OBJECT_LARGEOBJECT: case OBJECT_OPERATOR: case OBJECT_OPCLASS: case OBJECT_OPFAMILY: case OBJECT_TABLESPACE: case OBJECT_TSDICTIONARY: case OBJECT_TSCONFIGURATION: { Relation catalog; Relation relation; Oid classId; ObjectAddress address; address = get_object_address(stmt->objectType, stmt->object, stmt->objarg, &relation, AccessExclusiveLock, false); Assert(relation == NULL); classId = address.classId; /* * XXX - get_object_address returns Oid of pg_largeobject * catalog for OBJECT_LARGEOBJECT because of historical * reasons. Fix up it here. */ if (classId == LargeObjectRelationId) classId = LargeObjectMetadataRelationId; catalog = heap_open(classId, RowExclusiveLock); AlterObjectOwner_internal(catalog, address.objectId, newowner); heap_close(catalog, RowExclusiveLock); return address.objectId; } break; default: elog(ERROR, "unrecognized AlterOwnerStmt type: %d", (int) stmt->objectType); return InvalidOid; /* keep compiler happy */ } }
Oid ExecRenameStmt | ( | RenameStmt * | stmt | ) |
Definition at line 301 of file alter.c.
References AccessExclusiveLock, AlterObjectRename_internal(), Assert, ObjectAddress::classId, elog, ERROR, get_object_address(), heap_close, heap_open(), RenameStmt::newname, NULL, RenameStmt::objarg, RenameStmt::object, OBJECT_AGGREGATE, OBJECT_ATTRIBUTE, OBJECT_COLLATION, OBJECT_COLUMN, OBJECT_CONSTRAINT, OBJECT_CONVERSION, OBJECT_DATABASE, OBJECT_DOMAIN, OBJECT_EVENT_TRIGGER, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FOREIGN_TABLE, OBJECT_FUNCTION, OBJECT_INDEX, OBJECT_LANGUAGE, OBJECT_MATVIEW, OBJECT_OPCLASS, OBJECT_OPFAMILY, OBJECT_ROLE, OBJECT_RULE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TRIGGER, OBJECT_TSCONFIGURATION, OBJECT_TSDICTIONARY, OBJECT_TSPARSER, OBJECT_TSTEMPLATE, OBJECT_TYPE, OBJECT_VIEW, ObjectAddress::objectId, RenameStmt::relation, renameatt(), RenameConstraint(), RenameDatabase(), RenameRelation(), RenameRewriteRule(), RenameRole(), RenameSchema(), RenameTableSpace(), renametrig(), RenameType(), RenameStmt::renameType, RowExclusiveLock, and RenameStmt::subname.
Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().
{ switch (stmt->renameType) { case OBJECT_CONSTRAINT: return RenameConstraint(stmt); case OBJECT_DATABASE: return RenameDatabase(stmt->subname, stmt->newname); case OBJECT_ROLE: return RenameRole(stmt->subname, stmt->newname); case OBJECT_SCHEMA: return RenameSchema(stmt->subname, stmt->newname); case OBJECT_TABLESPACE: return RenameTableSpace(stmt->subname, stmt->newname); case OBJECT_TABLE: case OBJECT_SEQUENCE: case OBJECT_VIEW: case OBJECT_MATVIEW: case OBJECT_INDEX: case OBJECT_FOREIGN_TABLE: return RenameRelation(stmt); case OBJECT_COLUMN: case OBJECT_ATTRIBUTE: return renameatt(stmt); case OBJECT_RULE: return RenameRewriteRule(stmt->relation, stmt->subname, stmt->newname); case OBJECT_TRIGGER: return renametrig(stmt); case OBJECT_DOMAIN: case OBJECT_TYPE: return RenameType(stmt); case OBJECT_AGGREGATE: case OBJECT_COLLATION: case OBJECT_CONVERSION: case OBJECT_EVENT_TRIGGER: case OBJECT_FDW: case OBJECT_FOREIGN_SERVER: case OBJECT_FUNCTION: case OBJECT_OPCLASS: case OBJECT_OPFAMILY: case OBJECT_LANGUAGE: case OBJECT_TSCONFIGURATION: case OBJECT_TSDICTIONARY: case OBJECT_TSPARSER: case OBJECT_TSTEMPLATE: { ObjectAddress address; Relation catalog; Relation relation; address = get_object_address(stmt->renameType, stmt->object, stmt->objarg, &relation, AccessExclusiveLock, false); Assert(relation == NULL); catalog = heap_open(address.classId, RowExclusiveLock); AlterObjectRename_internal(catalog, address.objectId, stmt->newname); heap_close(catalog, RowExclusiveLock); return address.objectId; } default: elog(ERROR, "unrecognized rename stmt type: %d", (int) stmt->renameType); return InvalidOid; /* keep compiler happy */ } }