@@ -37,37 +37,38 @@ static int numCatalogIds = 0;
3737
3838/*
3939 * These variables are static to avoid the notational cruft of having to pass
40- * them into findTableByOid() and friends. For each of these arrays, we
41- * build a sorted-by-OID index array immediately after it's built, and then
42- * we use binary search in findTableByOid() and friends. (qsort'ing the base
43- * arrays themselves would be simpler, but it doesn't work because pg_dump.c
44- * may have already established pointers between items.)
45- */
46- static TableInfo * tblinfo ;
47- static TypeInfo * typinfo ;
48- static FuncInfo * funinfo ;
49- static OprInfo * oprinfo ;
50- static NamespaceInfo * nspinfo ;
51- static int numTables ;
52- static int numTypes ;
53- static int numFuncs ;
54- static int numOperators ;
55- static int numCollations ;
56- static int numNamespaces ;
40+ * them into findTableByOid() and friends. For each of these arrays, we build
41+ * a sorted-by-OID index array immediately after the objects are fetched,
42+ * and then we use binary search in findTableByOid() and friends. (qsort'ing
43+ * the object arrays themselves would be simpler, but it doesn't work because
44+ * pg_dump.c may have already established pointers between items.)
45+ */
5746static DumpableObject * * tblinfoindex ;
5847static DumpableObject * * typinfoindex ;
5948static DumpableObject * * funinfoindex ;
6049static DumpableObject * * oprinfoindex ;
6150static DumpableObject * * collinfoindex ;
6251static DumpableObject * * nspinfoindex ;
52+ static DumpableObject * * extinfoindex ;
53+ static int numTables ;
54+ static int numTypes ;
55+ static int numFuncs ;
56+ static int numOperators ;
57+ static int numCollations ;
58+ static int numNamespaces ;
59+ static int numExtensions ;
6360
61+ /* This is an array of object identities, not actual DumpableObjects */
62+ static ExtensionMemberId * extmembers ;
63+ static int numextmembers ;
6464
6565static void flagInhTables (TableInfo * tbinfo , int numTables ,
6666 InhInfo * inhinfo , int numInherits );
6767static void flagInhAttrs (TableInfo * tblinfo , int numTables );
6868static DumpableObject * * buildIndexArray (void * objArray , int numObjs ,
6969 Size objSize );
7070static int DOCatalogIdCompare (const void * p1 , const void * p2 );
71+ static int ExtensionMemberIdCompare (const void * p1 , const void * p2 );
7172static void findParentsByOid (TableInfo * self ,
7273 InhInfo * inhinfo , int numInherits );
7374static int strInArray (const char * pattern , char * * arr , int arr_size );
@@ -80,10 +81,14 @@ static int strInArray(const char *pattern, char **arr, int arr_size);
8081TableInfo *
8182getSchemaData (Archive * fout , int * numTablesPtr )
8283{
84+ TableInfo * tblinfo ;
85+ TypeInfo * typinfo ;
86+ FuncInfo * funinfo ;
87+ OprInfo * oprinfo ;
88+ CollInfo * collinfo ;
89+ NamespaceInfo * nspinfo ;
8390 ExtensionInfo * extinfo ;
8491 InhInfo * inhinfo ;
85- CollInfo * collinfo ;
86- int numExtensions ;
8792 int numAggregates ;
8893 int numInherits ;
8994 int numRules ;
@@ -101,6 +106,20 @@ getSchemaData(Archive *fout, int *numTablesPtr)
101106 int numDefaultACLs ;
102107 int numEventTriggers ;
103108
109+ /*
110+ * We must read extensions and extension membership info first, because
111+ * extension membership needs to be consultable during decisions about
112+ * whether other objects are to be dumped.
113+ */
114+ if (g_verbose )
115+ write_msg (NULL , "reading extensions\n" );
116+ extinfo = getExtensions (fout , & numExtensions );
117+ extinfoindex = buildIndexArray (extinfo , numExtensions , sizeof (ExtensionInfo ));
118+
119+ if (g_verbose )
120+ write_msg (NULL , "identifying extension members\n" );
121+ getExtensionMembership (fout , extinfo , numExtensions );
122+
104123 if (g_verbose )
105124 write_msg (NULL , "reading schemas\n" );
106125 nspinfo = getNamespaces (fout , & numNamespaces );
@@ -120,10 +139,6 @@ getSchemaData(Archive *fout, int *numTablesPtr)
120139 /* Do this after we've built tblinfoindex */
121140 getOwnedSeqs (fout , tblinfo , numTables );
122141
123- if (g_verbose )
124- write_msg (NULL , "reading extensions\n" );
125- extinfo = getExtensions (fout , & numExtensions );
126-
127142 if (g_verbose )
128143 write_msg (NULL , "reading user-defined functions\n" );
129144 funinfo = getFuncs (fout , & numFuncs );
@@ -206,14 +221,10 @@ getSchemaData(Archive *fout, int *numTablesPtr)
206221 write_msg (NULL , "reading event triggers\n" );
207222 getEventTriggers (fout , & numEventTriggers );
208223
209- /*
210- * Identify extension member objects and mark them as not to be dumped.
211- * This must happen after reading all objects that can be direct members
212- * of extensions, but before we begin to process table subsidiary objects.
213- */
224+ /* Identify extension configuration tables that should be dumped */
214225 if (g_verbose )
215- write_msg (NULL , "finding extension members \n" );
216- getExtensionMembership (fout , extinfo , numExtensions );
226+ write_msg (NULL , "finding extension tables \n" );
227+ processExtensionTables (fout , extinfo , numExtensions );
217228
218229 /* Link tables to parents, mark parents of target tables interesting */
219230 if (g_verbose )
@@ -752,6 +763,93 @@ findNamespaceByOid(Oid oid)
752763 return (NamespaceInfo * ) findObjectByOid (oid , nspinfoindex , numNamespaces );
753764}
754765
766+ /*
767+ * findExtensionByOid
768+ * finds the entry (in extinfo) of the extension with the given oid
769+ * returns NULL if not found
770+ */
771+ ExtensionInfo *
772+ findExtensionByOid (Oid oid )
773+ {
774+ return (ExtensionInfo * ) findObjectByOid (oid , extinfoindex , numExtensions );
775+ }
776+
777+
778+ /*
779+ * setExtensionMembership
780+ * accept and save data about which objects belong to extensions
781+ */
782+ void
783+ setExtensionMembership (ExtensionMemberId * extmems , int nextmems )
784+ {
785+ /* Sort array in preparation for binary searches */
786+ if (nextmems > 1 )
787+ qsort ((void * ) extmems , nextmems , sizeof (ExtensionMemberId ),
788+ ExtensionMemberIdCompare );
789+ /* And save */
790+ extmembers = extmems ;
791+ numextmembers = nextmems ;
792+ }
793+
794+ /*
795+ * findOwningExtension
796+ * return owning extension for specified catalog ID, or NULL if none
797+ */
798+ ExtensionInfo *
799+ findOwningExtension (CatalogId catalogId )
800+ {
801+ ExtensionMemberId * low ;
802+ ExtensionMemberId * high ;
803+
804+ /*
805+ * We could use bsearch() here, but the notational cruft of calling
806+ * bsearch is nearly as bad as doing it ourselves; and the generalized
807+ * bsearch function is noticeably slower as well.
808+ */
809+ if (numextmembers <= 0 )
810+ return NULL ;
811+ low = extmembers ;
812+ high = extmembers + (numextmembers - 1 );
813+ while (low <= high )
814+ {
815+ ExtensionMemberId * middle ;
816+ int difference ;
817+
818+ middle = low + (high - low ) / 2 ;
819+ /* comparison must match ExtensionMemberIdCompare, below */
820+ difference = oidcmp (middle -> catId .oid , catalogId .oid );
821+ if (difference == 0 )
822+ difference = oidcmp (middle -> catId .tableoid , catalogId .tableoid );
823+ if (difference == 0 )
824+ return middle -> ext ;
825+ else if (difference < 0 )
826+ low = middle + 1 ;
827+ else
828+ high = middle - 1 ;
829+ }
830+ return NULL ;
831+ }
832+
833+ /*
834+ * qsort comparator for ExtensionMemberIds
835+ */
836+ static int
837+ ExtensionMemberIdCompare (const void * p1 , const void * p2 )
838+ {
839+ const ExtensionMemberId * obj1 = (const ExtensionMemberId * ) p1 ;
840+ const ExtensionMemberId * obj2 = (const ExtensionMemberId * ) p2 ;
841+ int cmpval ;
842+
843+ /*
844+ * Compare OID first since it's usually unique, whereas there will only be
845+ * a few distinct values of tableoid.
846+ */
847+ cmpval = oidcmp (obj1 -> catId .oid , obj2 -> catId .oid );
848+ if (cmpval == 0 )
849+ cmpval = oidcmp (obj1 -> catId .tableoid , obj2 -> catId .tableoid );
850+ return cmpval ;
851+ }
852+
755853
756854/*
757855 * findParentsByOid
0 commit comments