Commit 0e549697 authored by Robert Haas's avatar Robert Haas

Classify DROP operations by whether or not they are user-initiated.

This doesn't do anything useful just yet, but is intended as supporting
infrastructure for allowing sepgsql to sensibly check DROP permissions.

KaiGai Kohei and Robert Haas
parent bc334748
...@@ -1211,7 +1211,7 @@ SetDefaultACL(InternalDefaultACL *iacls) ...@@ -1211,7 +1211,7 @@ SetDefaultACL(InternalDefaultACL *iacls)
myself.objectId = HeapTupleGetOid(tuple); myself.objectId = HeapTupleGetOid(tuple);
myself.objectSubId = 0; myself.objectSubId = 0;
performDeletion(&myself, DROP_RESTRICT); performDeletion(&myself, DROP_RESTRICT, 0);
} }
} }
else else
......
...@@ -171,7 +171,8 @@ static void reportDependentObjects(const ObjectAddresses *targetObjects, ...@@ -171,7 +171,8 @@ static void reportDependentObjects(const ObjectAddresses *targetObjects,
DropBehavior behavior, DropBehavior behavior,
int msglevel, int msglevel,
const ObjectAddress *origObject); const ObjectAddress *origObject);
static void deleteOneObject(const ObjectAddress *object, Relation depRel); static void deleteOneObject(const ObjectAddress *object,
Relation depRel, int32 flags);
static void doDeletion(const ObjectAddress *object); static void doDeletion(const ObjectAddress *object);
static void AcquireDeletionLock(const ObjectAddress *object); static void AcquireDeletionLock(const ObjectAddress *object);
static void ReleaseDeletionLock(const ObjectAddress *object); static void ReleaseDeletionLock(const ObjectAddress *object);
...@@ -205,10 +206,17 @@ static void getOpFamilyDescription(StringInfo buffer, Oid opfid); ...@@ -205,10 +206,17 @@ static void getOpFamilyDescription(StringInfo buffer, Oid opfid);
* that can participate in dependencies. Note that the next two routines * that can participate in dependencies. Note that the next two routines
* are variants on the same theme; if you change anything here you'll likely * are variants on the same theme; if you change anything here you'll likely
* need to fix them too. * need to fix them too.
*
* flags should include PERFORM_DELETION_INTERNAL when the drop operation is
* not the direct result of a user-initiated action. For example, when a
* temporary schema is cleaned out so that a new backend can use it, or when
* a column default is dropped as an intermediate step while adding a new one,
* that's an internal operation. On the other hand, when the we drop something
* because the user issued a DROP statement against it, that's not internal.
*/ */
void void
performDeletion(const ObjectAddress *object, performDeletion(const ObjectAddress *object,
DropBehavior behavior) DropBehavior behavior, int flags)
{ {
Relation depRel; Relation depRel;
ObjectAddresses *targetObjects; ObjectAddresses *targetObjects;
...@@ -254,7 +262,7 @@ performDeletion(const ObjectAddress *object, ...@@ -254,7 +262,7 @@ performDeletion(const ObjectAddress *object,
{ {
ObjectAddress *thisobj = targetObjects->refs + i; ObjectAddress *thisobj = targetObjects->refs + i;
deleteOneObject(thisobj, depRel); deleteOneObject(thisobj, depRel, flags);
} }
/* And clean up */ /* And clean up */
...@@ -274,7 +282,7 @@ performDeletion(const ObjectAddress *object, ...@@ -274,7 +282,7 @@ performDeletion(const ObjectAddress *object,
*/ */
void void
performMultipleDeletions(const ObjectAddresses *objects, performMultipleDeletions(const ObjectAddresses *objects,
DropBehavior behavior) DropBehavior behavior, int flags)
{ {
Relation depRel; Relation depRel;
ObjectAddresses *targetObjects; ObjectAddresses *targetObjects;
...@@ -336,7 +344,7 @@ performMultipleDeletions(const ObjectAddresses *objects, ...@@ -336,7 +344,7 @@ performMultipleDeletions(const ObjectAddresses *objects,
{ {
ObjectAddress *thisobj = targetObjects->refs + i; ObjectAddress *thisobj = targetObjects->refs + i;
deleteOneObject(thisobj, depRel); deleteOneObject(thisobj, depRel, flags);
} }
/* And clean up */ /* And clean up */
...@@ -407,7 +415,14 @@ deleteWhatDependsOn(const ObjectAddress *object, ...@@ -407,7 +415,14 @@ deleteWhatDependsOn(const ObjectAddress *object,
if (thisextra->flags & DEPFLAG_ORIGINAL) if (thisextra->flags & DEPFLAG_ORIGINAL)
continue; continue;
deleteOneObject(thisobj, depRel); /*
* Since this function is currently only used to clean out temporary
* schemas, we pass PERFORM_DELETION_INTERNAL here, indicating that
* the operation is an automatic system operation rather than a user
* action. If, in the future, this function is used for other
* purposes, we might need to revisit this.
*/
deleteOneObject(thisobj, depRel, PERFORM_DELETION_INTERNAL);
} }
/* And clean up */ /* And clean up */
...@@ -950,7 +965,7 @@ reportDependentObjects(const ObjectAddresses *targetObjects, ...@@ -950,7 +965,7 @@ reportDependentObjects(const ObjectAddresses *targetObjects,
* depRel is the already-open pg_depend relation. * depRel is the already-open pg_depend relation.
*/ */
static void static void
deleteOneObject(const ObjectAddress *object, Relation depRel) deleteOneObject(const ObjectAddress *object, Relation depRel, int flags)
{ {
ScanKeyData key[3]; ScanKeyData key[3];
int nkeys; int nkeys;
......
...@@ -1528,7 +1528,7 @@ RemoveAttributeById(Oid relid, AttrNumber attnum) ...@@ -1528,7 +1528,7 @@ RemoveAttributeById(Oid relid, AttrNumber attnum)
*/ */
void void
RemoveAttrDefault(Oid relid, AttrNumber attnum, RemoveAttrDefault(Oid relid, AttrNumber attnum,
DropBehavior behavior, bool complain) DropBehavior behavior, bool complain, bool internal)
{ {
Relation attrdef_rel; Relation attrdef_rel;
ScanKeyData scankeys[2]; ScanKeyData scankeys[2];
...@@ -1559,7 +1559,8 @@ RemoveAttrDefault(Oid relid, AttrNumber attnum, ...@@ -1559,7 +1559,8 @@ RemoveAttrDefault(Oid relid, AttrNumber attnum,
object.objectId = HeapTupleGetOid(tuple); object.objectId = HeapTupleGetOid(tuple);
object.objectSubId = 0; object.objectSubId = 0;
performDeletion(&object, behavior); performDeletion(&object, behavior,
internal ? PERFORM_DELETION_INTERNAL : 0);
found = true; found = true;
} }
......
...@@ -1240,7 +1240,7 @@ shdepDropOwned(List *roleids, DropBehavior behavior) ...@@ -1240,7 +1240,7 @@ shdepDropOwned(List *roleids, DropBehavior behavior)
} }
/* the dependency mechanism does the actual work */ /* the dependency mechanism does the actual work */
performMultipleDeletions(deleteobjs, behavior); performMultipleDeletions(deleteobjs, behavior, 0);
heap_close(sdepRel, RowExclusiveLock); heap_close(sdepRel, RowExclusiveLock);
......
...@@ -1443,7 +1443,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, ...@@ -1443,7 +1443,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
* The new relation is local to our transaction and we know nothing * The new relation is local to our transaction and we know nothing
* depends on it, so DROP_RESTRICT should be OK. * depends on it, so DROP_RESTRICT should be OK.
*/ */
performDeletion(&object, DROP_RESTRICT); performDeletion(&object, DROP_RESTRICT, PERFORM_DELETION_INTERNAL);
/* performDeletion does CommandCounterIncrement at end */ /* performDeletion does CommandCounterIncrement at end */
......
...@@ -119,7 +119,7 @@ RemoveObjects(DropStmt *stmt) ...@@ -119,7 +119,7 @@ RemoveObjects(DropStmt *stmt)
} }
/* Here we really delete them. */ /* Here we really delete them. */
performMultipleDeletions(objects, stmt->behavior); performMultipleDeletions(objects, stmt->behavior, 0);
free_object_addresses(objects); free_object_addresses(objects);
} }
......
...@@ -1286,7 +1286,7 @@ RemoveUserMapping(DropUserMappingStmt *stmt) ...@@ -1286,7 +1286,7 @@ RemoveUserMapping(DropUserMappingStmt *stmt)
object.objectId = umId; object.objectId = umId;
object.objectSubId = 0; object.objectSubId = 0;
performDeletion(&object, DROP_CASCADE); performDeletion(&object, DROP_CASCADE, 0);
} }
......
...@@ -1519,7 +1519,7 @@ dropOperators(List *opfamilyname, Oid amoid, Oid opfamilyoid, ...@@ -1519,7 +1519,7 @@ dropOperators(List *opfamilyname, Oid amoid, Oid opfamilyoid,
object.objectId = amopid; object.objectId = amopid;
object.objectSubId = 0; object.objectSubId = 0;
performDeletion(&object, DROP_RESTRICT); performDeletion(&object, DROP_RESTRICT, 0);
} }
} }
...@@ -1559,7 +1559,7 @@ dropProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid, ...@@ -1559,7 +1559,7 @@ dropProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid,
object.objectId = amprocid; object.objectId = amprocid;
object.objectSubId = 0; object.objectSubId = 0;
performDeletion(&object, DROP_RESTRICT); performDeletion(&object, DROP_RESTRICT, 0);
} }
} }
......
...@@ -816,7 +816,7 @@ RemoveRelations(DropStmt *drop) ...@@ -816,7 +816,7 @@ RemoveRelations(DropStmt *drop)
add_exact_object_address(&obj, objects); add_exact_object_address(&obj, objects);
} }
performMultipleDeletions(objects, drop->behavior); performMultipleDeletions(objects, drop->behavior, 0);
free_object_addresses(objects); free_object_addresses(objects);
} }
...@@ -4803,8 +4803,13 @@ ATExecColumnDefault(Relation rel, const char *colName, ...@@ -4803,8 +4803,13 @@ ATExecColumnDefault(Relation rel, const char *colName,
* Remove any old default for the column. We use RESTRICT here for * Remove any old default for the column. We use RESTRICT here for
* safety, but at present we do not expect anything to depend on the * safety, but at present we do not expect anything to depend on the
* default. * default.
*
* We treat removing the existing default as an internal operation when
* it is preparatory to adding a new default, but as a user-initiated
* operation when the user asked for a drop.
*/ */
RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, false); RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, false,
newDefault == NULL ? false : true);
if (newDefault) if (newDefault)
{ {
...@@ -5217,7 +5222,7 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName, ...@@ -5217,7 +5222,7 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
object.objectId = RelationGetRelid(rel); object.objectId = RelationGetRelid(rel);
object.objectSubId = attnum; object.objectSubId = attnum;
performDeletion(&object, behavior); performDeletion(&object, behavior, 0);
/* /*
* If we dropped the OID column, must adjust pg_class.relhasoids and tell * If we dropped the OID column, must adjust pg_class.relhasoids and tell
...@@ -6731,7 +6736,7 @@ ATExecDropConstraint(Relation rel, const char *constrName, ...@@ -6731,7 +6736,7 @@ ATExecDropConstraint(Relation rel, const char *constrName,
conobj.objectId = HeapTupleGetOid(tuple); conobj.objectId = HeapTupleGetOid(tuple);
conobj.objectSubId = 0; conobj.objectSubId = 0;
performDeletion(&conobj, behavior); performDeletion(&conobj, behavior, 0);
found = true; found = true;
...@@ -7453,7 +7458,8 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, ...@@ -7453,7 +7458,8 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
* We use RESTRICT here for safety, but at present we do not expect * We use RESTRICT here for safety, but at present we do not expect
* anything to depend on the default. * anything to depend on the default.
*/ */
RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, true); RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, true,
true);
StoreAttrDefault(rel, attnum, defaultexpr); StoreAttrDefault(rel, attnum, defaultexpr);
} }
...@@ -7598,7 +7604,7 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) ...@@ -7598,7 +7604,7 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode)
obj.classId = ConstraintRelationId; obj.classId = ConstraintRelationId;
obj.objectId = lfirst_oid(oid_item); obj.objectId = lfirst_oid(oid_item);
obj.objectSubId = 0; obj.objectSubId = 0;
performDeletion(&obj, DROP_RESTRICT); performDeletion(&obj, DROP_RESTRICT, PERFORM_DELETION_INTERNAL);
} }
foreach(oid_item, tab->changedIndexOids) foreach(oid_item, tab->changedIndexOids)
...@@ -7606,7 +7612,7 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) ...@@ -7606,7 +7612,7 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode)
obj.classId = RelationRelationId; obj.classId = RelationRelationId;
obj.objectId = lfirst_oid(oid_item); obj.objectId = lfirst_oid(oid_item);
obj.objectSubId = 0; obj.objectSubId = 0;
performDeletion(&obj, DROP_RESTRICT); performDeletion(&obj, DROP_RESTRICT, PERFORM_DELETION_INTERNAL);
} }
/* /*
...@@ -9764,7 +9770,14 @@ PreCommit_on_commit_actions(void) ...@@ -9764,7 +9770,14 @@ PreCommit_on_commit_actions(void)
object.classId = RelationRelationId; object.classId = RelationRelationId;
object.objectId = oc->relid; object.objectId = oc->relid;
object.objectSubId = 0; object.objectSubId = 0;
performDeletion(&object, DROP_CASCADE);
/*
* Since this is an automatic drop, rather than one
* directly initiated by the user, we pass the
* PERFORM_DELETION_INTERNAL flag.
*/
performDeletion(&object,
DROP_CASCADE, PERFORM_DELETION_INTERNAL);
/* /*
* Note that table deletion will call * Note that table deletion will call
......
...@@ -2318,7 +2318,7 @@ AlterDomainDropConstraint(List *names, const char *constrName, ...@@ -2318,7 +2318,7 @@ AlterDomainDropConstraint(List *names, const char *constrName,
conobj.objectId = HeapTupleGetOid(contup); conobj.objectId = HeapTupleGetOid(contup);
conobj.objectSubId = 0; conobj.objectSubId = 0;
performDeletion(&conobj, behavior); performDeletion(&conobj, behavior, 0);
found = true; found = true;
} }
} }
......
...@@ -2044,7 +2044,7 @@ do_autovacuum(void) ...@@ -2044,7 +2044,7 @@ do_autovacuum(void)
object.classId = RelationRelationId; object.classId = RelationRelationId;
object.objectId = relid; object.objectId = relid;
object.objectSubId = 0; object.objectSubId = 0;
performDeletion(&object, DROP_CASCADE); performDeletion(&object, DROP_CASCADE, PERFORM_DELETION_INTERNAL);
} }
else else
{ {
......
...@@ -307,7 +307,7 @@ inv_drop(Oid lobjId) ...@@ -307,7 +307,7 @@ inv_drop(Oid lobjId)
object.classId = LargeObjectRelationId; object.classId = LargeObjectRelationId;
object.objectId = lobjId; object.objectId = lobjId;
object.objectSubId = 0; object.objectSubId = 0;
performDeletion(&object, DROP_CASCADE); performDeletion(&object, DROP_CASCADE, 0);
/* /*
* Advance command counter so that tuple removal will be seen by later * Advance command counter so that tuple removal will be seen by later
......
...@@ -152,11 +152,13 @@ typedef enum ObjectClass ...@@ -152,11 +152,13 @@ typedef enum ObjectClass
/* in dependency.c */ /* in dependency.c */
#define PERFORM_DELETION_INTERNAL 0x0001
extern void performDeletion(const ObjectAddress *object, extern void performDeletion(const ObjectAddress *object,
DropBehavior behavior); DropBehavior behavior, int flags);
extern void performMultipleDeletions(const ObjectAddresses *objects, extern void performMultipleDeletions(const ObjectAddresses *objects,
DropBehavior behavior); DropBehavior behavior, int flags);
extern void deleteWhatDependsOn(const ObjectAddress *object, extern void deleteWhatDependsOn(const ObjectAddress *object,
bool showNotices); bool showNotices);
......
...@@ -107,7 +107,7 @@ extern void DeleteRelationTuple(Oid relid); ...@@ -107,7 +107,7 @@ extern void DeleteRelationTuple(Oid relid);
extern void DeleteAttributeTuples(Oid relid); extern void DeleteAttributeTuples(Oid relid);
extern void RemoveAttributeById(Oid relid, AttrNumber attnum); extern void RemoveAttributeById(Oid relid, AttrNumber attnum);
extern void RemoveAttrDefault(Oid relid, AttrNumber attnum, extern void RemoveAttrDefault(Oid relid, AttrNumber attnum,
DropBehavior behavior, bool complain); DropBehavior behavior, bool complain, bool internal);
extern void RemoveAttrDefaultById(Oid attrdefId); extern void RemoveAttrDefaultById(Oid attrdefId);
extern void RemoveStatistics(Oid relid, AttrNumber attnum); extern void RemoveStatistics(Oid relid, AttrNumber attnum);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment