15
15
*
16
16
*
17
17
* 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 $
19
19
*
20
20
*-------------------------------------------------------------------------
21
21
*/
@@ -134,7 +134,8 @@ static bool has_lock_conflicts(TocEntry *te1, TocEntry *te2);
134
134
static void repoint_table_dependencies (ArchiveHandle * AH ,
135
135
DumpId tableId , DumpId tableDataId );
136
136
static void identify_locking_dependencies (TocEntry * te ,
137
- TocEntry * * tocsByDumpId );
137
+ TocEntry * * tocsByDumpId ,
138
+ DumpId maxDumpId );
138
139
static void reduce_dependencies (ArchiveHandle * AH , TocEntry * te ,
139
140
TocEntry * ready_list );
140
141
static void mark_create_done (ArchiveHandle * AH , TocEntry * te );
@@ -3091,6 +3092,10 @@ restore_toc_entries_parallel(ArchiveHandle *AH)
3091
3092
if (AH -> ClonePtr == NULL || AH -> ReopenPtr == NULL )
3092
3093
die_horribly (AH , modulename , "parallel restore is not supported with this archive file format\n" );
3093
3094
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
+
3094
3099
slots = (ParallelSlot * ) calloc (sizeof (ParallelSlot ), n_slots );
3095
3100
3096
3101
/* Adjust dependency information */
@@ -3649,17 +3654,23 @@ fix_dependencies(ArchiveHandle *AH)
3649
3654
{
3650
3655
TocEntry * * tocsByDumpId ;
3651
3656
TocEntry * te ;
3657
+ DumpId maxDumpId ;
3652
3658
int i ;
3653
3659
3654
3660
/*
3655
3661
* For some of the steps here, it is convenient to have an array that
3656
3662
* indexes the TOC entries by dump ID, rather than searching the TOC list
3657
3663
* repeatedly. Entries for dump IDs not present in the TOC will be NULL.
3658
3664
*
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
+ *
3659
3669
* Also, initialize the depCount fields, and make sure all the TOC items
3660
3670
* are marked as not being in any parallel-processing list.
3661
3671
*/
3662
- tocsByDumpId = (TocEntry * * ) calloc (AH -> maxDumpId , sizeof (TocEntry * ));
3672
+ maxDumpId = AH -> maxDumpId ;
3673
+ tocsByDumpId = (TocEntry * * ) calloc (maxDumpId , sizeof (TocEntry * ));
3663
3674
for (te = AH -> toc -> next ; te != AH -> toc ; te = te -> next )
3664
3675
{
3665
3676
tocsByDumpId [te -> dumpId - 1 ] = te ;
@@ -3688,7 +3699,8 @@ fix_dependencies(ArchiveHandle *AH)
3688
3699
{
3689
3700
DumpId tableId = te -> dependencies [0 ];
3690
3701
3691
- if (tocsByDumpId [tableId - 1 ] == NULL ||
3702
+ if (tableId > maxDumpId ||
3703
+ tocsByDumpId [tableId - 1 ] == NULL ||
3692
3704
strcmp (tocsByDumpId [tableId - 1 ]-> desc , "TABLE" ) == 0 )
3693
3705
{
3694
3706
repoint_table_dependencies (AH , tableId , te -> dumpId );
@@ -3733,7 +3745,9 @@ fix_dependencies(ArchiveHandle *AH)
3733
3745
{
3734
3746
for (i = 0 ; i < te -> nDeps ; i ++ )
3735
3747
{
3736
- if (tocsByDumpId [te -> dependencies [i ] - 1 ] == NULL )
3748
+ DumpId depid = te -> dependencies [i ];
3749
+
3750
+ if (depid > maxDumpId || tocsByDumpId [depid - 1 ] == NULL )
3737
3751
te -> depCount -- ;
3738
3752
}
3739
3753
}
@@ -3745,7 +3759,7 @@ fix_dependencies(ArchiveHandle *AH)
3745
3759
{
3746
3760
te -> lockDeps = NULL ;
3747
3761
te -> nLockDeps = 0 ;
3748
- identify_locking_dependencies (te , tocsByDumpId );
3762
+ identify_locking_dependencies (te , tocsByDumpId , maxDumpId );
3749
3763
}
3750
3764
3751
3765
free (tocsByDumpId );
@@ -3782,11 +3796,13 @@ repoint_table_dependencies(ArchiveHandle *AH,
3782
3796
* Identify which objects we'll need exclusive lock on in order to restore
3783
3797
* the given TOC entry (*other* than the one identified by the TOC entry
3784
3798
* itself). Record their dump IDs in the entry's lockDeps[] array.
3785
- * tocsByDumpId[] is a convenience array to 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.
3787
3801
*/
3788
3802
static void
3789
- identify_locking_dependencies (TocEntry * te , TocEntry * * tocsByDumpId )
3803
+ identify_locking_dependencies (TocEntry * te ,
3804
+ TocEntry * * tocsByDumpId ,
3805
+ DumpId maxDumpId )
3790
3806
{
3791
3807
DumpId * lockids ;
3792
3808
int nlockids ;
@@ -3817,7 +3833,7 @@ identify_locking_dependencies(TocEntry *te, TocEntry **tocsByDumpId)
3817
3833
{
3818
3834
DumpId depid = te -> dependencies [i ];
3819
3835
3820
- if (tocsByDumpId [depid - 1 ] &&
3836
+ if (depid <= maxDumpId && tocsByDumpId [depid - 1 ] &&
3821
3837
strcmp (tocsByDumpId [depid - 1 ]-> desc , "TABLE DATA" ) == 0 )
3822
3838
lockids [nlockids ++ ] = depid ;
3823
3839
}
0 commit comments