1515 *
1616 *
1717 * IDENTIFICATION
18- *$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.177 2009/12/14 00 :39:10 itagaki Exp $
18+ *$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.178 2010/01/19 18 :39:19 tgl Exp $
1919 *
2020 *-------------------------------------------------------------------------
2121 */
@@ -134,7 +134,8 @@ static bool has_lock_conflicts(TocEntry *te1, TocEntry *te2);
134134static void repoint_table_dependencies (ArchiveHandle * AH ,
135135DumpId tableId ,DumpId tableDataId );
136136static void identify_locking_dependencies (TocEntry * te ,
137- TocEntry * * tocsByDumpId );
137+ TocEntry * * tocsByDumpId ,
138+ DumpId maxDumpId );
138139static void reduce_dependencies (ArchiveHandle * AH ,TocEntry * te ,
139140TocEntry * ready_list );
140141static void mark_create_done (ArchiveHandle * AH ,TocEntry * te );
@@ -3091,6 +3092,10 @@ restore_toc_entries_parallel(ArchiveHandle *AH)
30913092if (AH -> ClonePtr == NULL || AH -> ReopenPtr == NULL )
30923093die_horribly (AH ,modulename ,"parallel restore is not supported with this archive file format\n" );
30933094
3095+ /* doesn't work if the archive represents dependencies as OIDs, either */
3096+ if (AH -> version < K_VERS_1_8 )
3097+ die_horribly (AH ,modulename ,"parallel restore is not supported with archives made by pre-8.0 pg_dump\n" );
3098+
30943099slots = (ParallelSlot * )calloc (sizeof (ParallelSlot ),n_slots );
30953100
30963101/* Adjust dependency information */
@@ -3649,17 +3654,23 @@ fix_dependencies(ArchiveHandle *AH)
36493654{
36503655TocEntry * * tocsByDumpId ;
36513656TocEntry * te ;
3657+ DumpId maxDumpId ;
36523658int i ;
36533659
36543660/*
36553661 * For some of the steps here, it is convenient to have an array that
36563662 * indexes the TOC entries by dump ID, rather than searching the TOC list
36573663 * repeatedly.Entries for dump IDs not present in the TOC will be NULL.
36583664 *
3665+ * NOTE: because maxDumpId is just the highest dump ID defined in the
3666+ * archive, there might be dependencies for IDs > maxDumpId. All uses
3667+ * of this array must guard against out-of-range dependency numbers.
3668+ *
36593669 * Also, initialize the depCount fields, and make sure all the TOC items
36603670 * are marked as not being in any parallel-processing list.
36613671 */
3662- tocsByDumpId = (TocEntry * * )calloc (AH -> maxDumpId ,sizeof (TocEntry * ));
3672+ maxDumpId = AH -> maxDumpId ;
3673+ tocsByDumpId = (TocEntry * * )calloc (maxDumpId ,sizeof (TocEntry * ));
36633674for (te = AH -> toc -> next ;te != AH -> toc ;te = te -> next )
36643675{
36653676tocsByDumpId [te -> dumpId - 1 ]= te ;
@@ -3688,7 +3699,8 @@ fix_dependencies(ArchiveHandle *AH)
36883699{
36893700DumpId tableId = te -> dependencies [0 ];
36903701
3691- if (tocsByDumpId [tableId - 1 ]== NULL ||
3702+ if (tableId > maxDumpId ||
3703+ tocsByDumpId [tableId - 1 ]== NULL ||
36923704strcmp (tocsByDumpId [tableId - 1 ]-> desc ,"TABLE" )== 0 )
36933705{
36943706repoint_table_dependencies (AH ,tableId ,te -> dumpId );
@@ -3733,7 +3745,9 @@ fix_dependencies(ArchiveHandle *AH)
37333745{
37343746for (i = 0 ;i < te -> nDeps ;i ++ )
37353747{
3736- if (tocsByDumpId [te -> dependencies [i ]- 1 ]== NULL )
3748+ DumpId depid = te -> dependencies [i ];
3749+
3750+ if (depid > maxDumpId || tocsByDumpId [depid - 1 ]== NULL )
37373751te -> depCount -- ;
37383752}
37393753}
@@ -3745,7 +3759,7 @@ fix_dependencies(ArchiveHandle *AH)
37453759{
37463760te -> lockDeps = NULL ;
37473761te -> nLockDeps = 0 ;
3748- identify_locking_dependencies (te ,tocsByDumpId );
3762+ identify_locking_dependencies (te ,tocsByDumpId , maxDumpId );
37493763}
37503764
37513765free (tocsByDumpId );
@@ -3782,11 +3796,13 @@ repoint_table_dependencies(ArchiveHandle *AH,
37823796 * Identify which objects we'll need exclusive lock on in order to restore
37833797 * the given TOC entry (*other* than the one identified by the TOC entry
37843798 * itself). Record their dump IDs in the entry's lockDeps[] array.
3785- * tocsByDumpId[] is a convenience arrayto avoid searching the TOC
3786- * for each dependency.
3799+ * tocsByDumpId[] is a convenience array(of size maxDumpId) to avoid
3800+ *searching the TOC for each dependency.
37873801 */
37883802static void
3789- identify_locking_dependencies (TocEntry * te ,TocEntry * * tocsByDumpId )
3803+ identify_locking_dependencies (TocEntry * te ,
3804+ TocEntry * * tocsByDumpId ,
3805+ DumpId maxDumpId )
37903806{
37913807DumpId * lockids ;
37923808int nlockids ;
@@ -3817,7 +3833,7 @@ identify_locking_dependencies(TocEntry *te, TocEntry **tocsByDumpId)
38173833{
38183834DumpId depid = te -> dependencies [i ];
38193835
3820- if (tocsByDumpId [depid - 1 ]&&
3836+ if (depid <= maxDumpId && tocsByDumpId [depid - 1 ]&&
38213837strcmp (tocsByDumpId [depid - 1 ]-> desc ,"TABLE DATA" )== 0 )
38223838lockids [nlockids ++ ]= depid ;
38233839}