]> granicus.if.org Git - postgresql/commitdiff
Sort the dependent objects before deletion in DROP OWNED BY.
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 20 Mar 2019 22:06:29 +0000 (18:06 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 20 Mar 2019 22:06:29 +0000 (18:06 -0400)
This finishes a task we left undone in commit f1ad067fc, by extending
the delete-in-descending-OID-order rule to deletions triggered by
DROP OWNED BY.  We've coped with machine-dependent deletion orders
one time too many, and the new issues caused by Peter G's recent
nbtree hacking seem like the last straw.

Discussion: https://postgr.es/m/E1h6eep-0001Mw-Vd@gemulon.postgresql.org

src/backend/catalog/dependency.c
src/backend/catalog/pg_shdepend.c
src/include/catalog/dependency.h

index 2048d71535bf2903b7ea93d89aa4449e598897eb..f7acb4103ebd1407b63221e9de5d62561704b665 100644 (file)
@@ -2610,6 +2610,23 @@ record_object_address_dependencies(const ObjectAddress *depender,
                                                           behavior);
 }
 
+/*
+ * Sort the items in an ObjectAddresses array.
+ *
+ * The major sort key is OID-descending, so that newer objects will be listed
+ * first in most cases.  This is primarily useful for ensuring stable outputs
+ * from regression tests; it's not recommended if the order of the objects is
+ * determined by user input, such as the order of targets in a DROP command.
+ */
+void
+sort_object_addresses(ObjectAddresses *addrs)
+{
+       if (addrs->numrefs > 1)
+               qsort((void *) addrs->refs, addrs->numrefs,
+                         sizeof(ObjectAddress),
+                         object_address_comparator);
+}
+
 /*
  * Clean up when done with an ObjectAddresses array.
  */
index 1619c1c8a7ccfcbfb70b55fda7379c09a85a6ce1..63a7f4838f818e278e1e16c90ece3da9613f3ff0 100644 (file)
@@ -1266,6 +1266,14 @@ shdepDropOwned(List *roleids, DropBehavior behavior)
                systable_endscan(scan);
        }
 
+       /*
+        * For stability of deletion-report ordering, sort the objects into
+        * approximate reverse creation order before deletion.  (This might also
+        * make the deletion go a bit faster, since there's less chance of having
+        * to rearrange the objects due to dependencies.)
+        */
+       sort_object_addresses(deleteobjs);
+
        /* the dependency mechanism does the actual work */
        performMultipleDeletions(deleteobjs, behavior, 0);
 
index b235a23f5dc602b52bf9c5405757dedf54c9d99e..f537f0158799e18304deb76eaa503ed6679c485d 100644 (file)
@@ -170,6 +170,8 @@ extern void record_object_address_dependencies(const ObjectAddress *depender,
                                                                   ObjectAddresses *referenced,
                                                                   DependencyType behavior);
 
+extern void sort_object_addresses(ObjectAddresses *addrs);
+
 extern void free_object_addresses(ObjectAddresses *addrs);
 
 /* in pg_depend.c */