19
19
*
20
20
*
21
21
* IDENTIFICATION
22
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_custom.c,v 1.44 2009/08/24 14:15:09 alvherre Exp $
22
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_custom.c,v 1.45 2010/06/27 19:07:24 tgl Exp $
23
23
*
24
24
*-------------------------------------------------------------------------
25
25
*/
@@ -438,26 +438,24 @@ static void
438
438
_PrintTocData (ArchiveHandle * AH , TocEntry * te , RestoreOptions * ropt )
439
439
{
440
440
lclContext * ctx = (lclContext * ) AH -> formatData ;
441
- int id ;
442
441
lclTocEntry * tctx = (lclTocEntry * ) te -> formatData ;
443
442
int blkType ;
443
+ int id ;
444
444
445
445
if (tctx -> dataState == K_OFFSET_NO_DATA )
446
446
return ;
447
447
448
448
if (!ctx -> hasSeek || tctx -> dataState == K_OFFSET_POS_NOT_SET )
449
449
{
450
- /* Skip over unnecessary blocks until we get the one we want. */
451
-
450
+ /*
451
+ * We cannot seek directly to the desired block. Instead, skip
452
+ * over block headers until we find the one we want. This could
453
+ * fail if we are asked to restore items out-of-order.
454
+ */
452
455
_readBlockHeader (AH , & blkType , & id );
453
456
454
- while (id != te -> dumpId )
457
+ while (blkType != EOF && id != te -> dumpId )
455
458
{
456
- if ((TocIDRequired (AH , id , ropt ) & REQ_DATA ) != 0 )
457
- die_horribly (AH , modulename ,
458
- "dumping a specific TOC data block out of order is not supported"
459
- " without ID on this input stream (fseek required)\n" );
460
-
461
459
switch (blkType )
462
460
{
463
461
case BLK_DATA :
@@ -479,13 +477,33 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
479
477
}
480
478
else
481
479
{
482
- /* Grab it */
480
+ /* We can just seek to the place we need to be. */
483
481
if (fseeko (AH -> FH , tctx -> dataPos , SEEK_SET ) != 0 )
484
- die_horribly (AH , modulename , "error during file seek: %s\n" , strerror (errno ));
482
+ die_horribly (AH , modulename , "error during file seek: %s\n" ,
483
+ strerror (errno ));
485
484
486
485
_readBlockHeader (AH , & blkType , & id );
487
486
}
488
487
488
+ /* Produce suitable failure message if we fell off end of file */
489
+ if (blkType == EOF )
490
+ {
491
+ if (tctx -> dataState == K_OFFSET_POS_NOT_SET )
492
+ die_horribly (AH , modulename , "could not find block ID %d in archive -- "
493
+ "possibly due to out-of-order restore request, "
494
+ "which cannot be handled due to lack of data offsets in archive\n" ,
495
+ te -> dumpId );
496
+ else if (!ctx -> hasSeek )
497
+ die_horribly (AH , modulename , "could not find block ID %d in archive -- "
498
+ "possibly due to out-of-order restore request, "
499
+ "which cannot be handled due to non-seekable input file\n" ,
500
+ te -> dumpId );
501
+ else /* huh, the dataPos led us to EOF? */
502
+ die_horribly (AH , modulename , "could not find block ID %d in archive -- "
503
+ "possibly corrupt archive\n" ,
504
+ te -> dumpId );
505
+ }
506
+
489
507
/* Are we sane? */
490
508
if (id != te -> dumpId )
491
509
die_horribly (AH , modulename , "found unexpected block ID (%d) when reading data -- expected %d\n" ,
@@ -907,15 +925,35 @@ _getFilePos(ArchiveHandle *AH, lclContext *ctx)
907
925
908
926
/*
909
927
* Read a data block header. The format changed in V1.3, so we
910
- * put the code here for simplicity.
928
+ * centralize the code here for simplicity. Returns *type = EOF
929
+ * if at EOF.
911
930
*/
912
931
static void
913
932
_readBlockHeader (ArchiveHandle * AH , int * type , int * id )
914
933
{
934
+ lclContext * ctx = (lclContext * ) AH -> formatData ;
935
+ int byt ;
936
+
937
+ /*
938
+ * Note: if we are at EOF with a pre-1.3 input file, we'll die_horribly
939
+ * inside ReadInt rather than returning EOF. It doesn't seem worth
940
+ * jumping through hoops to deal with that case better, because no such
941
+ * files are likely to exist in the wild: only some 7.1 development
942
+ * versions of pg_dump ever generated such files.
943
+ */
915
944
if (AH -> version < K_VERS_1_3 )
916
945
* type = BLK_DATA ;
917
946
else
918
- * type = _ReadByte (AH );
947
+ {
948
+ byt = getc (AH -> FH );
949
+ * type = byt ;
950
+ if (byt == EOF )
951
+ {
952
+ * id = 0 ; /* don't return an uninitialized value */
953
+ return ;
954
+ }
955
+ ctx -> filePos += 1 ;
956
+ }
919
957
920
958
* id = ReadInt (AH );
921
959
}
0 commit comments