]> granicus.if.org Git - postgresql/commitdiff
Classify DROP operations by whether or not they are user-initiated.
authorRobert Haas <rhaas@postgresql.org>
Thu, 26 Jan 2012 14:24:54 +0000 (09:24 -0500)
committerRobert Haas <rhaas@postgresql.org>
Thu, 26 Jan 2012 14:30:27 +0000 (09:30 -0500)
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

14 files changed:
src/backend/catalog/aclchk.c
src/backend/catalog/dependency.c
src/backend/catalog/heap.c
src/backend/catalog/pg_shdepend.c
src/backend/commands/cluster.c
src/backend/commands/dropcmds.c
src/backend/commands/foreigncmds.c
src/backend/commands/opclasscmds.c
src/backend/commands/tablecmds.c
src/backend/commands/typecmds.c
src/backend/postmaster/autovacuum.c
src/backend/storage/large_object/inv_api.c
src/include/catalog/dependency.h
src/include/catalog/heap.h

index f5e6a3f061980e20d7dfddebce6667ea18d98c91..9315e79c991d81dcc35881d4ae24fcb71ea30804 100644 (file)
@@ -1211,7 +1211,7 @@ SetDefaultACL(InternalDefaultACL *iacls)
                        myself.objectId = HeapTupleGetOid(tuple);
                        myself.objectSubId = 0;
 
-                       performDeletion(&myself, DROP_RESTRICT);
+                       performDeletion(&myself, DROP_RESTRICT, 0);
                }
        }
        else
index 0b3d489ae006d15e916a23ba885afc75f4c9fa46..db86262b4f06ec5b78f834eb10fbae45a1e77033 100644 (file)
@@ -171,7 +171,8 @@ static void reportDependentObjects(const ObjectAddresses *targetObjects,
                                           DropBehavior behavior,
                                           int msglevel,
                                           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 AcquireDeletionLock(const ObjectAddress *object);
 static void ReleaseDeletionLock(const ObjectAddress *object);
@@ -205,10 +206,17 @@ static void getOpFamilyDescription(StringInfo buffer, Oid opfid);
  * 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
  * 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
 performDeletion(const ObjectAddress *object,
-                               DropBehavior behavior)
+                               DropBehavior behavior, int flags)
 {
        Relation        depRel;
        ObjectAddresses *targetObjects;
@@ -254,7 +262,7 @@ performDeletion(const ObjectAddress *object,
        {
                ObjectAddress *thisobj = targetObjects->refs + i;
 
-               deleteOneObject(thisobj, depRel);
+               deleteOneObject(thisobj, depRel, flags);
        }
 
        /* And clean up */
@@ -274,7 +282,7 @@ performDeletion(const ObjectAddress *object,
  */
 void
 performMultipleDeletions(const ObjectAddresses *objects,
-                                                DropBehavior behavior)
+                                                DropBehavior behavior, int flags)
 {
        Relation        depRel;
        ObjectAddresses *targetObjects;
@@ -336,7 +344,7 @@ performMultipleDeletions(const ObjectAddresses *objects,
        {
                ObjectAddress *thisobj = targetObjects->refs + i;
 
-               deleteOneObject(thisobj, depRel);
+               deleteOneObject(thisobj, depRel, flags);
        }
 
        /* And clean up */
@@ -407,7 +415,14 @@ deleteWhatDependsOn(const ObjectAddress *object,
                if (thisextra->flags & DEPFLAG_ORIGINAL)
                        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 */
@@ -950,7 +965,7 @@ reportDependentObjects(const ObjectAddresses *targetObjects,
  * depRel is the already-open pg_depend relation.
  */
 static void
-deleteOneObject(const ObjectAddress *object, Relation depRel)
+deleteOneObject(const ObjectAddress *object, Relation depRel, int flags)
 {
        ScanKeyData key[3];
        int                     nkeys;
index 204236f550eb096fa5ea850835f89b515ee5bc83..aef410ae9b2156e94ee06b12ffcfd2897d83b461 100644 (file)
@@ -1528,7 +1528,7 @@ RemoveAttributeById(Oid relid, AttrNumber attnum)
  */
 void
 RemoveAttrDefault(Oid relid, AttrNumber attnum,
-                                 DropBehavior behavior, bool complain)
+                                 DropBehavior behavior, bool complain, bool internal)
 {
        Relation        attrdef_rel;
        ScanKeyData scankeys[2];
@@ -1559,7 +1559,8 @@ RemoveAttrDefault(Oid relid, AttrNumber attnum,
                object.objectId = HeapTupleGetOid(tuple);
                object.objectSubId = 0;
 
-               performDeletion(&object, behavior);
+               performDeletion(&object, behavior,
+                                               internal ? PERFORM_DELETION_INTERNAL : 0);
 
                found = true;
        }
index c3e55ab6a7afacd7f240b4d910c848d962d68b37..11cb9883a762a30bb86eb1a23437459fcc26fd8c 100644 (file)
@@ -1240,7 +1240,7 @@ shdepDropOwned(List *roleids, DropBehavior behavior)
        }
 
        /* the dependency mechanism does the actual work */
-       performMultipleDeletions(deleteobjs, behavior);
+       performMultipleDeletions(deleteobjs, behavior, 0);
 
        heap_close(sdepRel, RowExclusiveLock);
 
index 9408f259a611f45d0bb2777cd597f80317ec774b..349d13034e32975356c755e76533ac76d704abd2 100644 (file)
@@ -1443,7 +1443,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
         * The new relation is local to our transaction and we know nothing
         * 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 */
 
index 9eeba041cffd840e71ddbd229b197aeb683877ef..298940c7c42ba15f966b285c5b4ed86526ac90e7 100644 (file)
@@ -119,7 +119,7 @@ RemoveObjects(DropStmt *stmt)
        }
 
        /* Here we really delete them. */
-       performMultipleDeletions(objects, stmt->behavior);
+       performMultipleDeletions(objects, stmt->behavior, 0);
 
        free_object_addresses(objects);
 }
index a9ec904c357afbb68f78e1f270aca7a66cdf2e9f..4135e268575f46bc8afe43179b0beed19f74e7c1 100644 (file)
@@ -1286,7 +1286,7 @@ RemoveUserMapping(DropUserMappingStmt *stmt)
        object.objectId = umId;
        object.objectSubId = 0;
 
-       performDeletion(&object, DROP_CASCADE);
+       performDeletion(&object, DROP_CASCADE, 0);
 }
 
 
index 5dca0222fdf28a63e4beca5b40d5d95fa234b2a7..5dc131a50e2221d01804ee2a57cf6de68e86bdfd 100644 (file)
@@ -1519,7 +1519,7 @@ dropOperators(List *opfamilyname, Oid amoid, Oid opfamilyoid,
                object.objectId = amopid;
                object.objectSubId = 0;
 
-               performDeletion(&object, DROP_RESTRICT);
+               performDeletion(&object, DROP_RESTRICT, 0);
        }
 }
 
@@ -1559,7 +1559,7 @@ dropProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid,
                object.objectId = amprocid;
                object.objectSubId = 0;
 
-               performDeletion(&object, DROP_RESTRICT);
+               performDeletion(&object, DROP_RESTRICT, 0);
        }
 }
 
index cb8ac67812ab9ba9c9fab1135f623b82acc62fa6..9172d999310e76b7153ea70b410e7c6a738864ef 100644 (file)
@@ -816,7 +816,7 @@ RemoveRelations(DropStmt *drop)
                add_exact_object_address(&obj, objects);
        }
 
-       performMultipleDeletions(objects, drop->behavior);
+       performMultipleDeletions(objects, drop->behavior, 0);
 
        free_object_addresses(objects);
 }
@@ -4803,8 +4803,13 @@ ATExecColumnDefault(Relation rel, const char *colName,
         * 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
         * 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)
        {
@@ -5217,7 +5222,7 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
        object.objectId = RelationGetRelid(rel);
        object.objectSubId = attnum;
 
-       performDeletion(&object, behavior);
+       performDeletion(&object, behavior, 0);
 
        /*
         * If we dropped the OID column, must adjust pg_class.relhasoids and tell
@@ -6731,7 +6736,7 @@ ATExecDropConstraint(Relation rel, const char *constrName,
                conobj.objectId = HeapTupleGetOid(tuple);
                conobj.objectSubId = 0;
 
-               performDeletion(&conobj, behavior);
+               performDeletion(&conobj, behavior, 0);
 
                found = true;
 
@@ -7453,7 +7458,8 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
                 * We use RESTRICT here for safety, but at present we do not expect
                 * 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);
        }
@@ -7598,7 +7604,7 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode)
                obj.classId = ConstraintRelationId;
                obj.objectId = lfirst_oid(oid_item);
                obj.objectSubId = 0;
-               performDeletion(&obj, DROP_RESTRICT);
+               performDeletion(&obj, DROP_RESTRICT, PERFORM_DELETION_INTERNAL);
        }
 
        foreach(oid_item, tab->changedIndexOids)
@@ -7606,7 +7612,7 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode)
                obj.classId = RelationRelationId;
                obj.objectId = lfirst_oid(oid_item);
                obj.objectSubId = 0;
-               performDeletion(&obj, DROP_RESTRICT);
+               performDeletion(&obj, DROP_RESTRICT, PERFORM_DELETION_INTERNAL);
        }
 
        /*
@@ -9764,7 +9770,14 @@ PreCommit_on_commit_actions(void)
                                        object.classId = RelationRelationId;
                                        object.objectId = oc->relid;
                                        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
index 0043bf1fee29ec66829951199ebf55f82838b63a..03918486a15fba64d7c49d2da8574020d14af69c 100644 (file)
@@ -2318,7 +2318,7 @@ AlterDomainDropConstraint(List *names, const char *constrName,
                        conobj.objectId = HeapTupleGetOid(contup);
                        conobj.objectSubId = 0;
 
-                       performDeletion(&conobj, behavior);
+                       performDeletion(&conobj, behavior, 0);
                        found = true;
                }
        }
index e84e21c62cd83bb26bd495bcb2568b9dbac62dda..49c15c32616c385a55fe00929793be5a1189d4f0 100644 (file)
@@ -2044,7 +2044,7 @@ do_autovacuum(void)
                                        object.classId = RelationRelationId;
                                        object.objectId = relid;
                                        object.objectSubId = 0;
-                                       performDeletion(&object, DROP_CASCADE);
+                                       performDeletion(&object, DROP_CASCADE, PERFORM_DELETION_INTERNAL);
                                }
                                else
                                {
index afa572b3b1cd5781025e2a0f4a91639bc4c98830..a14ce442c1c35d3ab2d5e297060491206cc1dd84 100644 (file)
@@ -307,7 +307,7 @@ inv_drop(Oid lobjId)
        object.classId = LargeObjectRelationId;
        object.objectId = lobjId;
        object.objectSubId = 0;
-       performDeletion(&object, DROP_CASCADE);
+       performDeletion(&object, DROP_CASCADE, 0);
 
        /*
         * Advance command counter so that tuple removal will be seen by later
index 087341e5768371bb31fb0bc59ccc56d90ed62937..28e68c5ab59d63fb37a2e4d1976643e751423697 100644 (file)
@@ -152,11 +152,13 @@ typedef enum ObjectClass
 
 /* in dependency.c */
 
+#define PERFORM_DELETION_INTERNAL                      0x0001
+
 extern void performDeletion(const ObjectAddress *object,
-                               DropBehavior behavior);
+                               DropBehavior behavior, int flags);
 
 extern void performMultipleDeletions(const ObjectAddresses *objects,
-                                                DropBehavior behavior);
+                                                DropBehavior behavior, int flags);
 
 extern void deleteWhatDependsOn(const ObjectAddress *object,
                                        bool showNotices);
index 46bee44b5cf4f5d44243454efe09809dae646231..205538209689e9209f70b20e1697b6da0d1edf8b 100644 (file)
@@ -107,7 +107,7 @@ extern void DeleteRelationTuple(Oid relid);
 extern void DeleteAttributeTuples(Oid relid);
 extern void RemoveAttributeById(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 RemoveStatistics(Oid relid, AttrNumber attnum);