@@ -40,37 +40,38 @@ static int numCatalogIds = 0;
4040
4141/*
4242 * These variables are static to avoid the notational cruft of having to pass
43- * them into findTableByOid() and friends. For each of these arrays, we
44- * build a sorted-by-OID index array immediately after it's built, and then
45- * we use binary search in findTableByOid() and friends. (qsort'ing the base
46- * arrays themselves would be simpler, but it doesn't work because pg_dump.c
47- * may have already established pointers between items.)
48- */
49- static TableInfo * tblinfo ;
50- static TypeInfo * typinfo ;
51- static FuncInfo * funinfo ;
52- static OprInfo * oprinfo ;
53- static NamespaceInfo * nspinfo ;
54- static int numTables ;
55- static int numTypes ;
56- static int numFuncs ;
57- static int numOperators ;
58- static int numCollations ;
59- static int numNamespaces ;
43+ * them into findTableByOid() and friends. For each of these arrays, we build
44+ * a sorted-by-OID index array immediately after the objects are fetched,
45+ * and then we use binary search in findTableByOid() and friends. (qsort'ing
46+ * the object arrays themselves would be simpler, but it doesn't work because
47+ * pg_dump.c may have already established pointers between items.)
48+ */
6049static DumpableObject * * tblinfoindex ;
6150static DumpableObject * * typinfoindex ;
6251static DumpableObject * * funinfoindex ;
6352static DumpableObject * * oprinfoindex ;
6453static DumpableObject * * collinfoindex ;
6554static DumpableObject * * nspinfoindex ;
55+ static DumpableObject * * extinfoindex ;
56+ static int numTables ;
57+ static int numTypes ;
58+ static int numFuncs ;
59+ static int numOperators ;
60+ static int numCollations ;
61+ static int numNamespaces ;
62+ static int numExtensions ;
6663
64+ /* This is an array of object identities, not actual DumpableObjects */
65+ static ExtensionMemberId * extmembers ;
66+ static int numextmembers ;
6767
6868static void flagInhTables (TableInfo * tbinfo , int numTables ,
6969 InhInfo * inhinfo , int numInherits );
7070static void flagInhAttrs (DumpOptions * dopt , TableInfo * tblinfo , int numTables );
7171static DumpableObject * * buildIndexArray (void * objArray , int numObjs ,
7272 Size objSize );
7373static int DOCatalogIdCompare (const void * p1 , const void * p2 );
74+ static int ExtensionMemberIdCompare (const void * p1 , const void * p2 );
7475static void findParentsByOid (TableInfo * self ,
7576 InhInfo * inhinfo , int numInherits );
7677static int strInArray (const char * pattern , char * * arr , int arr_size );
@@ -83,10 +84,14 @@ static int strInArray(const char *pattern, char **arr, int arr_size);
8384TableInfo *
8485getSchemaData (Archive * fout , int * numTablesPtr )
8586{
87+ TableInfo * tblinfo ;
88+ TypeInfo * typinfo ;
89+ FuncInfo * funinfo ;
90+ OprInfo * oprinfo ;
91+ CollInfo * collinfo ;
92+ NamespaceInfo * nspinfo ;
8693 ExtensionInfo * extinfo ;
8794 InhInfo * inhinfo ;
88- CollInfo * collinfo ;
89- int numExtensions ;
9095 int numAggregates ;
9196 int numInherits ;
9297 int numRules ;
@@ -105,6 +110,20 @@ getSchemaData(Archive *fout, int *numTablesPtr)
105110 int numDefaultACLs ;
106111 int numEventTriggers ;
107112
113+ /*
114+ * We must read extensions and extension membership info first, because
115+ * extension membership needs to be consultable during decisions about
116+ * whether other objects are to be dumped.
117+ */
118+ if (g_verbose )
119+ write_msg (NULL , "reading extensions\n" );
120+ extinfo = getExtensions (fout , & numExtensions );
121+ extinfoindex = buildIndexArray (extinfo , numExtensions , sizeof (ExtensionInfo ));
122+
123+ if (g_verbose )
124+ write_msg (NULL , "identifying extension members\n" );
125+ getExtensionMembership (fout , extinfo , numExtensions );
126+
108127 if (g_verbose )
109128 write_msg (NULL , "reading schemas\n" );
110129 nspinfo = getNamespaces (fout , & numNamespaces );
@@ -124,10 +143,6 @@ getSchemaData(Archive *fout, int *numTablesPtr)
124143 /* Do this after we've built tblinfoindex */
125144 getOwnedSeqs (fout , tblinfo , numTables );
126145
127- if (g_verbose )
128- write_msg (NULL , "reading extensions\n" );
129- extinfo = getExtensions (fout , & numExtensions );
130-
131146 if (g_verbose )
132147 write_msg (NULL , "reading user-defined functions\n" );
133148 funinfo = getFuncs (fout , & numFuncs );
@@ -214,14 +229,10 @@ getSchemaData(Archive *fout, int *numTablesPtr)
214229 write_msg (NULL , "reading event triggers\n" );
215230 getEventTriggers (fout , & numEventTriggers );
216231
217- /*
218- * Identify extension member objects and mark them as not to be dumped.
219- * This must happen after reading all objects that can be direct members
220- * of extensions, but before we begin to process table subsidiary objects.
221- */
232+ /* Identify extension configuration tables that should be dumped */
222233 if (g_verbose )
223- write_msg (NULL , "finding extension members \n" );
224- getExtensionMembership (fout , extinfo , numExtensions );
234+ write_msg (NULL , "finding extension tables \n" );
235+ processExtensionTables (fout , extinfo , numExtensions );
225236
226237 /* Link tables to parents, mark parents of target tables interesting */
227238 if (g_verbose )
@@ -764,6 +775,93 @@ findNamespaceByOid(Oid oid)
764775 return (NamespaceInfo * ) findObjectByOid (oid , nspinfoindex , numNamespaces );
765776}
766777
778+ /*
779+ * findExtensionByOid
780+ * finds the entry (in extinfo) of the extension with the given oid
781+ * returns NULL if not found
782+ */
783+ ExtensionInfo *
784+ findExtensionByOid (Oid oid )
785+ {
786+ return (ExtensionInfo * ) findObjectByOid (oid , extinfoindex , numExtensions );
787+ }
788+
789+
790+ /*
791+ * setExtensionMembership
792+ * accept and save data about which objects belong to extensions
793+ */
794+ void
795+ setExtensionMembership (ExtensionMemberId * extmems , int nextmems )
796+ {
797+ /* Sort array in preparation for binary searches */
798+ if (nextmems > 1 )
799+ qsort ((void * ) extmems , nextmems , sizeof (ExtensionMemberId ),
800+ ExtensionMemberIdCompare );
801+ /* And save */
802+ extmembers = extmems ;
803+ numextmembers = nextmems ;
804+ }
805+
806+ /*
807+ * findOwningExtension
808+ * return owning extension for specified catalog ID, or NULL if none
809+ */
810+ ExtensionInfo *
811+ findOwningExtension (CatalogId catalogId )
812+ {
813+ ExtensionMemberId * low ;
814+ ExtensionMemberId * high ;
815+
816+ /*
817+ * We could use bsearch() here, but the notational cruft of calling
818+ * bsearch is nearly as bad as doing it ourselves; and the generalized
819+ * bsearch function is noticeably slower as well.
820+ */
821+ if (numextmembers <= 0 )
822+ return NULL ;
823+ low = extmembers ;
824+ high = extmembers + (numextmembers - 1 );
825+ while (low <= high )
826+ {
827+ ExtensionMemberId * middle ;
828+ int difference ;
829+
830+ middle = low + (high - low ) / 2 ;
831+ /* comparison must match ExtensionMemberIdCompare, below */
832+ difference = oidcmp (middle -> catId .oid , catalogId .oid );
833+ if (difference == 0 )
834+ difference = oidcmp (middle -> catId .tableoid , catalogId .tableoid );
835+ if (difference == 0 )
836+ return middle -> ext ;
837+ else if (difference < 0 )
838+ low = middle + 1 ;
839+ else
840+ high = middle - 1 ;
841+ }
842+ return NULL ;
843+ }
844+
845+ /*
846+ * qsort comparator for ExtensionMemberIds
847+ */
848+ static int
849+ ExtensionMemberIdCompare (const void * p1 , const void * p2 )
850+ {
851+ const ExtensionMemberId * obj1 = (const ExtensionMemberId * ) p1 ;
852+ const ExtensionMemberId * obj2 = (const ExtensionMemberId * ) p2 ;
853+ int cmpval ;
854+
855+ /*
856+ * Compare OID first since it's usually unique, whereas there will only be
857+ * a few distinct values of tableoid.
858+ */
859+ cmpval = oidcmp (obj1 -> catId .oid , obj2 -> catId .oid );
860+ if (cmpval == 0 )
861+ cmpval = oidcmp (obj1 -> catId .tableoid , obj2 -> catId .tableoid );
862+ return cmpval ;
863+ }
864+
767865
768866/*
769867 * findParentsByOid
0 commit comments