1515 *
1616 *
1717 * IDENTIFICATION
18- * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.22 2001/03/22 04:00:11 momjian Exp $
18+ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.23 2001/04/01 05:42:50 pjw Exp $
1919 *
2020 * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
2121 *
4141 * Modifications - 6-Mar-2001 - pjw@rhyme.com.au
4242 * - Only disable triggers in DataOnly (or implied data-only) restores.
4343 *
44+ * Modifications - 31-Mar-2001 - pjw@rhyme.com.au
45+ *
46+ * - Rudimentary support for dependencies in archives. Current implementation
47+ * uses dependencies to modify the OID used in sorting TOC entries.
48+ * This will NOT handle multi-level dependencies, but will manage simple
49+ * relationships like UDTs & their functions.
50+ *
51+ * - Treat OIDs with more respect (avoid using ints, use macros for
52+ * conversion & comparison).
53+ *
4454 *-------------------------------------------------------------------------
4555 */
4656
@@ -75,6 +85,8 @@ static TocEntry *_getTocEntry(ArchiveHandle *AH, int id);
7585static void _moveAfter (ArchiveHandle * AH , TocEntry * pos , TocEntry * te );
7686static void _moveBefore (ArchiveHandle * AH , TocEntry * pos , TocEntry * te );
7787static int _discoverArchiveFormat (ArchiveHandle * AH );
88+ static void _fixupOidInfo (TocEntry * te );
89+ static Oid _findMaxOID (const char * ((* deps )[]));
7890
7991static char * progname = "Archiver" ;
8092
@@ -557,7 +569,7 @@ WriteData(Archive *AHX, const void *data, int dLen)
557569/* Public */
558570void
559571ArchiveEntry (Archive * AHX , const char * oid , const char * name ,
560- const char * desc , const char * (deps []), const char * defn ,
572+ const char * desc , const char * (( * deps ) []), const char * defn ,
561573 const char * dropStmt , const char * copyStmt , const char * owner ,
562574 DataDumperPtr dumpFn , void * dumpArg )
563575{
@@ -577,10 +589,15 @@ ArchiveEntry(Archive *AHX, const char *oid, const char *name,
577589 AH -> toc -> prev = newToc ;
578590
579591 newToc -> id = AH -> lastID ;
580- newToc -> oid = strdup (oid );
581- newToc -> oidVal = atoi (oid );
592+
582593 newToc -> name = strdup (name );
583594 newToc -> desc = strdup (desc );
595+
596+ newToc -> oid = strdup (oid );
597+ newToc -> depOid = deps ;
598+ _fixupOidInfo (newToc );
599+
600+
584601 newToc -> defn = strdup (defn );
585602 newToc -> dropStmt = strdup (dropStmt );
586603 newToc -> copyStmt = copyStmt ? strdup (copyStmt ) : NULL ;
@@ -654,7 +671,7 @@ PrintTOCSummary(Archive *AHX, RestoreOptions *ropt)
654671
655672/* Called by a dumper to signal start of a BLOB */
656673int
657- StartBlob (Archive * AHX , int oid )
674+ StartBlob (Archive * AHX , Oid oid )
658675{
659676 ArchiveHandle * AH = (ArchiveHandle * ) AHX ;
660677
@@ -668,7 +685,7 @@ StartBlob(Archive *AHX, int oid)
668685
669686/* Called by a dumper to signal end of a BLOB */
670687int
671- EndBlob (Archive * AHX , int oid )
688+ EndBlob (Archive * AHX , Oid oid )
672689{
673690 ArchiveHandle * AH = (ArchiveHandle * ) AHX ;
674691
@@ -714,7 +731,7 @@ EndRestoreBlobs(ArchiveHandle *AH)
714731 * Called by a format handler to initiate restoration of a blob
715732 */
716733void
717- StartRestoreBlob (ArchiveHandle * AH , int oid )
734+ StartRestoreBlob (ArchiveHandle * AH , Oid oid )
718735{
719736 int loOid ;
720737
@@ -756,7 +773,7 @@ StartRestoreBlob(ArchiveHandle *AH, int oid)
756773}
757774
758775void
759- EndRestoreBlob (ArchiveHandle * AH , int oid )
776+ EndRestoreBlob (ArchiveHandle * AH , Oid oid )
760777{
761778 lo_close (AH -> connection , AH -> loFd );
762779 AH -> writingBlob = 0 ;
@@ -1331,7 +1348,7 @@ ReadInt(ArchiveHandle *AH)
13311348}
13321349
13331350int
1334- WriteStr (ArchiveHandle * AH , char * c )
1351+ WriteStr (ArchiveHandle * AH , const char * c )
13351352{
13361353 int res ;
13371354
@@ -1630,6 +1647,8 @@ void
16301647WriteToc (ArchiveHandle * AH )
16311648{
16321649 TocEntry * te = AH -> toc -> next ;
1650+ const char * dep ;
1651+ int i ;
16331652
16341653 /* printf("%d TOC Entries to save\n", AH->tocCount); */
16351654
@@ -1639,12 +1658,25 @@ WriteToc(ArchiveHandle *AH)
16391658 WriteInt (AH , te -> id );
16401659 WriteInt (AH , te -> dataDumper ? 1 : 0 );
16411660 WriteStr (AH , te -> oid );
1661+
16421662 WriteStr (AH , te -> name );
16431663 WriteStr (AH , te -> desc );
16441664 WriteStr (AH , te -> defn );
16451665 WriteStr (AH , te -> dropStmt );
16461666 WriteStr (AH , te -> copyStmt );
16471667 WriteStr (AH , te -> owner );
1668+
1669+ /* Dump list of dependencies */
1670+ if (te -> depOid != NULL )
1671+ {
1672+ i = 0 ;
1673+ while ( (dep = (* te -> depOid )[i ++ ]) != NULL )
1674+ {
1675+ WriteStr (AH , dep );
1676+ }
1677+ }
1678+ WriteStr (AH , NULL ); /* Terminate List */
1679+
16481680 if (AH -> WriteExtraTocPtr )
16491681 (* AH -> WriteExtraTocPtr ) (AH , te );
16501682 te = te -> next ;
@@ -1655,6 +1687,9 @@ void
16551687ReadToc (ArchiveHandle * AH )
16561688{
16571689 int i ;
1690+ char * ((* deps )[]);
1691+ int depIdx ;
1692+ int depSize ;
16581693
16591694 TocEntry * te = AH -> toc -> next ;
16601695
@@ -1672,7 +1707,8 @@ ReadToc(ArchiveHandle *AH)
16721707
16731708 te -> hadDumper = ReadInt (AH );
16741709 te -> oid = ReadStr (AH );
1675- te -> oidVal = atoi (te -> oid );
1710+ te -> oidVal = atooid (te -> oid );
1711+
16761712 te -> name = ReadStr (AH );
16771713 te -> desc = ReadStr (AH );
16781714 te -> defn = ReadStr (AH );
@@ -1683,6 +1719,40 @@ ReadToc(ArchiveHandle *AH)
16831719
16841720 te -> owner = ReadStr (AH );
16851721
1722+ /* Read TOC entry dependencies */
1723+ if (AH -> version >= K_VERS_1_5 )
1724+ {
1725+ depSize = 100 ;
1726+ deps = malloc (sizeof (char * ) * depSize );
1727+ depIdx = 0 ;
1728+ do
1729+ {
1730+ if (depIdx > depSize )
1731+ {
1732+ depSize *= 2 ;
1733+ deps = realloc (deps , sizeof (char * ) * depSize );
1734+ }
1735+ (* deps )[depIdx ] = ReadStr (AH );
1736+ /*
1737+ * if ((*deps)[depIdx])
1738+ * fprintf(stderr, "Read Dependency for %s -> %s\n", te->name, (*deps)[depIdx]);
1739+ */
1740+ } while ( (* deps )[depIdx ++ ] != NULL );
1741+
1742+ if (depIdx > 1 ) /* We have a non-null entry */
1743+ {
1744+ /* Trim it */
1745+ te -> depOid = realloc (deps , sizeof (char * ) * depIdx );
1746+ } else { /* No deps */
1747+ te -> depOid = NULL ;
1748+ }
1749+ } else {
1750+ te -> depOid = NULL ;
1751+ }
1752+
1753+ /* Set maxOidVal etc for use in sorting */
1754+ _fixupOidInfo (te );
1755+
16861756 if (AH -> ReadExtraTocPtr )
16871757 (* AH -> ReadExtraTocPtr ) (AH , te );
16881758
@@ -1984,17 +2054,50 @@ _tocSortCompareByOIDNum(const void *p1, const void *p2)
19842054{
19852055 TocEntry * te1 = * (TocEntry * * ) p1 ;
19862056 TocEntry * te2 = * (TocEntry * * ) p2 ;
1987- int id1 = te1 -> oidVal ;
1988- int id2 = te2 -> oidVal ;
2057+ Oid id1 = te1 -> maxOidVal ;
2058+ Oid id2 = te2 -> maxOidVal ;
2059+ int cmpval ;
19892060
19902061 /* printf("Comparing %d to %d\n", id1, id2); */
19912062
1992- if (id1 < id2 )
1993- return -1 ;
1994- else if (id1 > id2 )
1995- return 1 ;
1996- else
1997- return _tocSortCompareByIDNum (te1 , te2 );
2063+ cmpval = oidcmp (id1 , id2 );
2064+
2065+ /* If we have a deterministic answer, return it. */
2066+ if (cmpval != 0 )
2067+ return cmpval ;
2068+
2069+ /* More comparisons required */
2070+ if ( oideq (id1 , te1 -> maxDepOidVal ) ) /* maxOid1 came from deps */
2071+ {
2072+ if ( oideq (id2 , te2 -> maxDepOidVal ) ) /* maxOid2 also came from deps */
2073+ {
2074+ cmpval = oidcmp (te1 -> oidVal , te2 -> oidVal ); /* Just compare base OIDs */
2075+ }
2076+ else /* MaxOid2 was entry OID */
2077+ {
2078+ return 1 ; /* entry1 > entry2 */
2079+ };
2080+ }
2081+ else /* must have oideq(id1, te1->oidVal) => maxOid1 = Oid1 */
2082+ {
2083+ if ( oideq (id2 , te2 -> maxDepOidVal ) ) /* maxOid2 came from deps */
2084+ {
2085+ return -1 ; /* entry1 < entry2 */
2086+ }
2087+ else /* MaxOid2 was entry OID - deps don't matter */
2088+ {
2089+ cmpval = 0 ;
2090+ };
2091+ };
2092+
2093+ /* If we get here, then we've done another comparison
2094+ * Once again, a 0 result means we require even more
2095+ */
2096+ if (cmpval != 0 )
2097+ return cmpval ;
2098+
2099+ /* Entire OID details match, so use ID number (ie. original pg_dump order) */
2100+ return _tocSortCompareByIDNum (te1 , te2 );
19982101}
19992102
20002103static int
@@ -2015,6 +2118,48 @@ _tocSortCompareByIDNum(const void *p1, const void *p2)
20152118 return 0 ;
20162119}
20172120
2121+ /*
2122+ * Assuming Oid and depOid are set, work out the various
2123+ * Oid values used in sorting.
2124+ */
2125+ static void
2126+ _fixupOidInfo (TocEntry * te )
2127+ {
2128+ te -> oidVal = atooid (te -> oid );
2129+ te -> maxDepOidVal = _findMaxOID (te -> depOid );
2130+
2131+ /* For the purpose of sorting, find the max OID. */
2132+ if (oidcmp (te -> oidVal , te -> maxDepOidVal ) >= 0 )
2133+ te -> maxOidVal = te -> oidVal ;
2134+ else
2135+ te -> maxOidVal = te -> maxDepOidVal ;
2136+ }
2137+
2138+ /*
2139+ * Find the max OID value for a given list of string Oid values
2140+ */
2141+ static Oid
2142+ _findMaxOID (const char * ((* deps )[]))
2143+ {
2144+ const char * dep ;
2145+ int i ;
2146+ Oid maxOid = (Oid )0 ;
2147+ Oid currOid ;
2148+
2149+ if (!deps )
2150+ return maxOid ;
2151+
2152+ i = 0 ;
2153+ while ( (dep = (* deps )[i ++ ]) != NULL )
2154+ {
2155+ currOid = atooid (dep );
2156+ if (oidcmp (maxOid , currOid ) < 0 )
2157+ maxOid = currOid ;
2158+ }
2159+
2160+ return maxOid ;
2161+ }
2162+
20182163/*
20192164 * Maybe I can use this somewhere...
20202165 *
0 commit comments