15
15
*
16
16
*
17
17
* IDENTIFICATION
18
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.178 2010/01/19 18:39:19 tgl Exp $
18
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.179 2010/02/18 01:29:10 tgl Exp $
19
19
*
20
20
*-------------------------------------------------------------------------
21
21
*/
@@ -98,6 +98,7 @@ static void _selectTablespace(ArchiveHandle *AH, const char *tablespace);
98
98
static void processEncodingEntry (ArchiveHandle * AH , TocEntry * te );
99
99
static void processStdStringsEntry (ArchiveHandle * AH , TocEntry * te );
100
100
static teReqs _tocEntryRequired (TocEntry * te , RestoreOptions * ropt , bool include_acls );
101
+ static bool _tocEntryIsACL (TocEntry * te );
101
102
static void _disableTriggersIfNecessary (ArchiveHandle * AH , TocEntry * te , RestoreOptions * ropt );
102
103
static void _enableTriggersIfNecessary (ArchiveHandle * AH , TocEntry * te , RestoreOptions * ropt );
103
104
static TocEntry * getTocEntryByDumpId (ArchiveHandle * AH , DumpId id );
@@ -329,9 +330,9 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
329
330
AH -> currentTE = te ;
330
331
331
332
reqs = _tocEntryRequired (te , ropt , false /* needn't drop ACLs */ );
332
- if (((reqs & REQ_SCHEMA ) != 0 ) && te -> dropStmt )
333
+ /* We want anything that's selected and has a dropStmt */
334
+ if (((reqs & (REQ_SCHEMA |REQ_DATA )) != 0 ) && te -> dropStmt )
333
335
{
334
- /* We want the schema */
335
336
ahlog (AH , 1 , "dropping %s %s\n" , te -> desc , te -> tag );
336
337
/* Select owner and schema as necessary */
337
338
_becomeOwner (AH , te );
@@ -381,7 +382,8 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
381
382
/* Work out what, if anything, we want from this entry */
382
383
reqs = _tocEntryRequired (te , ropt , true);
383
384
384
- if ((reqs & REQ_SCHEMA ) != 0 ) /* We want the schema */
385
+ /* Both schema and data objects might now have ownership/ACLs */
386
+ if ((reqs & (REQ_SCHEMA |REQ_DATA )) != 0 )
385
387
{
386
388
ahlog (AH , 1 , "setting owner and privileges for %s %s\n" ,
387
389
te -> desc , te -> tag );
@@ -905,6 +907,7 @@ EndRestoreBlobs(ArchiveHandle *AH)
905
907
void
906
908
StartRestoreBlob (ArchiveHandle * AH , Oid oid , bool drop )
907
909
{
910
+ bool old_blob_style = (AH -> version < K_VERS_1_12 );
908
911
Oid loOid ;
909
912
910
913
AH -> blobCount ++ ;
@@ -914,24 +917,32 @@ StartRestoreBlob(ArchiveHandle *AH, Oid oid, bool drop)
914
917
915
918
ahlog (AH , 2 , "restoring large object with OID %u\n" , oid );
916
919
917
- if (drop )
920
+ /* With an old archive we must do drop and create logic here */
921
+ if (old_blob_style && drop )
918
922
DropBlobIfExists (AH , oid );
919
923
920
924
if (AH -> connection )
921
925
{
922
- loOid = lo_create (AH -> connection , oid );
923
- if (loOid == 0 || loOid != oid )
924
- die_horribly (AH , modulename , "could not create large object %u\n" ,
925
- oid );
926
-
926
+ if (old_blob_style )
927
+ {
928
+ loOid = lo_create (AH -> connection , oid );
929
+ if (loOid == 0 || loOid != oid )
930
+ die_horribly (AH , modulename , "could not create large object %u\n" ,
931
+ oid );
932
+ }
927
933
AH -> loFd = lo_open (AH -> connection , oid , INV_WRITE );
928
934
if (AH -> loFd == -1 )
929
- die_horribly (AH , modulename , "could not open large object\n" );
935
+ die_horribly (AH , modulename , "could not open large object %u\n" ,
936
+ oid );
930
937
}
931
938
else
932
939
{
933
- ahprintf (AH , "SELECT pg_catalog.lo_open(pg_catalog.lo_create('%u'), %d);\n" ,
934
- oid , INV_WRITE );
940
+ if (old_blob_style )
941
+ ahprintf (AH , "SELECT pg_catalog.lo_open(pg_catalog.lo_create('%u'), %d);\n" ,
942
+ oid , INV_WRITE );
943
+ else
944
+ ahprintf (AH , "SELECT pg_catalog.lo_open('%u', %d);\n" ,
945
+ oid , INV_WRITE );
935
946
}
936
947
937
948
AH -> writingBlob = 1 ;
@@ -1829,6 +1840,9 @@ _allocAH(const char *FileSpec, const ArchiveFormat fmt,
1829
1840
AH -> vmin = K_VERS_MINOR ;
1830
1841
AH -> vrev = K_VERS_REV ;
1831
1842
1843
+ /* Make a convenient integer <maj><min><rev>00 */
1844
+ AH -> version = ((AH -> vmaj * 256 + AH -> vmin ) * 256 + AH -> vrev ) * 256 + 0 ;
1845
+
1832
1846
/* initialize for backwards compatible string processing */
1833
1847
AH -> public .encoding = 0 ; /* PG_SQL_ASCII */
1834
1848
AH -> public .std_strings = false;
@@ -2068,12 +2082,13 @@ ReadToc(ArchiveHandle *AH)
2068
2082
else
2069
2083
{
2070
2084
/*
2071
- * rules for pre-8.4 archives wherein pg_dump hasn't classified
2072
- * the entries into sections
2085
+ * Rules for pre-8.4 archives wherein pg_dump hasn't classified
2086
+ * the entries into sections. This list need not cover entry
2087
+ * types added later than 8.4.
2073
2088
*/
2074
2089
if (strcmp (te -> desc , "COMMENT" ) == 0 ||
2075
2090
strcmp (te -> desc , "ACL" ) == 0 ||
2076
- strcmp (te -> desc , "DEFAULT ACL" ) == 0 )
2091
+ strcmp (te -> desc , "ACL LANGUAGE " ) == 0 )
2077
2092
te -> section = SECTION_NONE ;
2078
2093
else if (strcmp (te -> desc , "TABLE DATA" ) == 0 ||
2079
2094
strcmp (te -> desc , "BLOBS" ) == 0 ||
@@ -2228,10 +2243,10 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls)
2228
2243
return 0 ;
2229
2244
2230
2245
/* If it's an ACL, maybe ignore it */
2231
- if ((!include_acls || ropt -> aclsSkip ) &&
2232
- (strcmp (te -> desc , "ACL" ) == 0 || strcmp (te -> desc , "DEFAULT ACL" ) == 0 ))
2246
+ if ((!include_acls || ropt -> aclsSkip ) && _tocEntryIsACL (te ))
2233
2247
return 0 ;
2234
2248
2249
+ /* Ignore DATABASE entry unless we should create it */
2235
2250
if (!ropt -> create && strcmp (te -> desc , "DATABASE" ) == 0 )
2236
2251
return 0 ;
2237
2252
@@ -2286,9 +2301,18 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls)
2286
2301
if (!te -> hadDumper )
2287
2302
{
2288
2303
/*
2289
- * Special Case: If 'SEQUENCE SET' then it is considered a data entry
2304
+ * Special Case: If 'SEQUENCE SET' or anything to do with BLOBs,
2305
+ * then it is considered a data entry. We don't need to check for
2306
+ * the BLOBS entry or old-style BLOB COMMENTS, because they will
2307
+ * have hadDumper = true ... but we do need to check new-style
2308
+ * BLOB comments.
2290
2309
*/
2291
- if (strcmp (te -> desc , "SEQUENCE SET" ) == 0 )
2310
+ if (strcmp (te -> desc , "SEQUENCE SET" ) == 0 ||
2311
+ strcmp (te -> desc , "BLOB" ) == 0 ||
2312
+ (strcmp (te -> desc , "ACL" ) == 0 &&
2313
+ strncmp (te -> tag , "LARGE OBJECT " , 13 ) == 0 ) ||
2314
+ (strcmp (te -> desc , "COMMENT" ) == 0 &&
2315
+ strncmp (te -> tag , "LARGE OBJECT " , 13 ) == 0 ))
2292
2316
res = res & REQ_DATA ;
2293
2317
else
2294
2318
res = res & ~REQ_DATA ;
@@ -2320,6 +2344,20 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls)
2320
2344
return res ;
2321
2345
}
2322
2346
2347
+ /*
2348
+ * Identify TOC entries that are ACLs.
2349
+ */
2350
+ static bool
2351
+ _tocEntryIsACL (TocEntry * te )
2352
+ {
2353
+ /* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
2354
+ if (strcmp (te -> desc , "ACL" ) == 0 ||
2355
+ strcmp (te -> desc , "ACL LANGUAGE" ) == 0 ||
2356
+ strcmp (te -> desc , "DEFAULT ACL" ) == 0 )
2357
+ return true;
2358
+ return false;
2359
+ }
2360
+
2323
2361
/*
2324
2362
* Issue SET commands for parameters that we want to have set the same way
2325
2363
* at all times during execution of a restore script.
@@ -2685,6 +2723,13 @@ _getObjectDescription(PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH)
2685
2723
return ;
2686
2724
}
2687
2725
2726
+ /* BLOBs just have a name, but it's numeric so must not use fmtId */
2727
+ if (strcmp (type , "BLOB" ) == 0 )
2728
+ {
2729
+ appendPQExpBuffer (buf , "LARGE OBJECT %s" , te -> tag );
2730
+ return ;
2731
+ }
2732
+
2688
2733
/*
2689
2734
* These object types require additional decoration. Fortunately, the
2690
2735
* information needed is exactly what's in the DROP command.
@@ -2723,14 +2768,12 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
2723
2768
/* ACLs are dumped only during acl pass */
2724
2769
if (acl_pass )
2725
2770
{
2726
- if (!(strcmp (te -> desc , "ACL" ) == 0 ||
2727
- strcmp (te -> desc , "DEFAULT ACL" ) == 0 ))
2771
+ if (!_tocEntryIsACL (te ))
2728
2772
return ;
2729
2773
}
2730
2774
else
2731
2775
{
2732
- if (strcmp (te -> desc , "ACL" ) == 0 ||
2733
- strcmp (te -> desc , "DEFAULT ACL" ) == 0 )
2776
+ if (_tocEntryIsACL (te ))
2734
2777
return ;
2735
2778
}
2736
2779
@@ -2824,6 +2867,7 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
2824
2867
strlen (te -> owner ) > 0 && strlen (te -> dropStmt ) > 0 )
2825
2868
{
2826
2869
if (strcmp (te -> desc , "AGGREGATE" ) == 0 ||
2870
+ strcmp (te -> desc , "BLOB" ) == 0 ||
2827
2871
strcmp (te -> desc , "CONVERSION" ) == 0 ||
2828
2872
strcmp (te -> desc , "DATABASE" ) == 0 ||
2829
2873
strcmp (te -> desc , "DOMAIN" ) == 0 ||
@@ -2873,7 +2917,7 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
2873
2917
* If it's an ACL entry, it might contain SET SESSION AUTHORIZATION
2874
2918
* commands, so we can no longer assume we know the current auth setting.
2875
2919
*/
2876
- if (strncmp ( te -> desc , "ACL" , 3 ) == 0 )
2920
+ if (acl_pass )
2877
2921
{
2878
2922
if (AH -> currUser )
2879
2923
free (AH -> currUser );
0 commit comments