@@ -74,6 +74,13 @@ typedef enum
7474 REMOTE_OBJECT
7575} SharedDependencyObjectType ;
7676
77+ typedef struct
78+ {
79+ ObjectAddress object ;
80+ char deptype ;
81+ SharedDependencyObjectType objtype ;
82+ } ShDependObjectInfo ;
83+
7784static void getOidListDiff (Oid * list1 , int * nlist1 , Oid * list2 , int * nlist2 );
7885static Oid classIdGetDbId (Oid classId );
7986static void shdepChangeDep (Relation sdepRel ,
@@ -496,6 +503,56 @@ typedef struct
496503 int count ;
497504} remoteDep ;
498505
506+ /*
507+ * qsort comparator for ShDependObjectInfo items
508+ */
509+ static int
510+ shared_dependency_comparator (const void * a , const void * b )
511+ {
512+ const ShDependObjectInfo * obja = (const ShDependObjectInfo * ) a ;
513+ const ShDependObjectInfo * objb = (const ShDependObjectInfo * ) b ;
514+
515+ /*
516+ * Primary sort key is OID ascending.
517+ */
518+ if (obja -> object .objectId < objb -> object .objectId )
519+ return -1 ;
520+ if (obja -> object .objectId > objb -> object .objectId )
521+ return 1 ;
522+
523+ /*
524+ * Next sort on catalog ID, in case identical OIDs appear in different
525+ * catalogs. Sort direction is pretty arbitrary here.
526+ */
527+ if (obja -> object .classId < objb -> object .classId )
528+ return -1 ;
529+ if (obja -> object .classId > objb -> object .classId )
530+ return 1 ;
531+
532+ /*
533+ * Sort on object subId.
534+ *
535+ * We sort the subId as an unsigned int so that 0 (the whole object) will
536+ * come first.
537+ */
538+ if ((unsigned int ) obja -> object .objectSubId < (unsigned int ) objb -> object .objectSubId )
539+ return -1 ;
540+ if ((unsigned int ) obja -> object .objectSubId > (unsigned int ) objb -> object .objectSubId )
541+ return 1 ;
542+
543+ /*
544+ * Last, sort on deptype, in case the same object has multiple dependency
545+ * types. (Note that there's no need to consider objtype, as that's
546+ * determined by the catalog OID.)
547+ */
548+ if (obja -> deptype < objb -> deptype )
549+ return -1 ;
550+ if (obja -> deptype > objb -> deptype )
551+ return 1 ;
552+
553+ return 0 ;
554+ }
555+
499556/*
500557 * checkSharedDependencies
501558 *
@@ -531,16 +588,27 @@ checkSharedDependencies(Oid classId, Oid objectId,
531588 List * remDeps = NIL ;
532589 ListCell * cell ;
533590 ObjectAddress object ;
591+ ShDependObjectInfo * objects ;
592+ int numobjects ;
593+ int allocedobjects ;
534594 StringInfoData descs ;
535595 StringInfoData alldescs ;
536596
537597 /*
538598 * We limit the number of dependencies reported to the client to
539599 * MAX_REPORTED_DEPS, since client software may not deal well with
540600 * enormous error strings. The server log always gets a full report.
601+ *
602+ * For stability of regression test results, we sort local and shared
603+ * objects by OID before reporting them. We don't worry about the order
604+ * in which other databases are reported, though.
541605 */
542606#define MAX_REPORTED_DEPS 100
543607
608+ allocedobjects = 128 ; /* arbitrary initial array size */
609+ objects = (ShDependObjectInfo * )
610+ palloc (allocedobjects * sizeof (ShDependObjectInfo ));
611+ numobjects = 0 ;
544612 initStringInfo (& descs );
545613 initStringInfo (& alldescs );
546614
@@ -580,36 +648,26 @@ checkSharedDependencies(Oid classId, Oid objectId,
580648
581649 /*
582650 * If it's a dependency local to this database or it's a shared
583- * object, describe it.
651+ * object, add it to the objects array .
584652 *
585653 * If it's a remote dependency, keep track of it so we can report the
586654 * number of them later.
587655 */
588- if (sdepForm -> dbid == MyDatabaseId )
589- {
590- if (numReportedDeps < MAX_REPORTED_DEPS )
591- {
592- numReportedDeps ++ ;
593- storeObjectDescription (& descs , LOCAL_OBJECT , & object ,
594- sdepForm -> deptype , 0 );
595- }
596- else
597- numNotReportedDeps ++ ;
598- storeObjectDescription (& alldescs , LOCAL_OBJECT , & object ,
599- sdepForm -> deptype , 0 );
600- }
601- else if (sdepForm -> dbid == InvalidOid )
656+ if (sdepForm -> dbid == MyDatabaseId ||
657+ sdepForm -> dbid == InvalidOid )
602658 {
603- if (numReportedDeps < MAX_REPORTED_DEPS )
659+ if (numobjects >= allocedobjects )
604660 {
605- numReportedDeps ++ ;
606- storeObjectDescription (& descs , SHARED_OBJECT , & object ,
607- sdepForm -> deptype , 0 );
661+ allocedobjects *= 2 ;
662+ objects = (ShDependObjectInfo * )
663+ repalloc (objects ,
664+ allocedobjects * sizeof (ShDependObjectInfo ));
608665 }
609- else
610- numNotReportedDeps ++ ;
611- storeObjectDescription (& alldescs , SHARED_OBJECT , & object ,
612- sdepForm -> deptype , 0 );
666+ objects [numobjects ].object = object ;
667+ objects [numobjects ].deptype = sdepForm -> deptype ;
668+ objects [numobjects ].objtype = (sdepForm -> dbid == MyDatabaseId ) ?
669+ LOCAL_OBJECT : SHARED_OBJECT ;
670+ numobjects ++ ;
613671 }
614672 else
615673 {
@@ -647,6 +705,33 @@ checkSharedDependencies(Oid classId, Oid objectId,
647705
648706 table_close (sdepRel , AccessShareLock );
649707
708+ /*
709+ * Sort and report local and shared objects.
710+ */
711+ if (numobjects > 1 )
712+ qsort ((void * ) objects , numobjects ,
713+ sizeof (ShDependObjectInfo ), shared_dependency_comparator );
714+
715+ for (int i = 0 ; i < numobjects ; i ++ )
716+ {
717+ if (numReportedDeps < MAX_REPORTED_DEPS )
718+ {
719+ numReportedDeps ++ ;
720+ storeObjectDescription (& descs ,
721+ objects [i ].objtype ,
722+ & objects [i ].object ,
723+ objects [i ].deptype ,
724+ 0 );
725+ }
726+ else
727+ numNotReportedDeps ++ ;
728+ storeObjectDescription (& alldescs ,
729+ objects [i ].objtype ,
730+ & objects [i ].object ,
731+ objects [i ].deptype ,
732+ 0 );
733+ }
734+
650735 /*
651736 * Summarize dependencies in remote databases.
652737 */
@@ -670,6 +755,7 @@ checkSharedDependencies(Oid classId, Oid objectId,
670755 SHARED_DEPENDENCY_INVALID , dep -> count );
671756 }
672757
758+ pfree (objects );
673759 list_free_deep (remDeps );
674760
675761 if (descs .len == 0 )
0 commit comments