1515 *
1616 *
1717 * 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 $
1919 *
2020 *-------------------------------------------------------------------------
2121 */
@@ -98,6 +98,7 @@ static void _selectTablespace(ArchiveHandle *AH, const char *tablespace);
9898static void processEncodingEntry (ArchiveHandle * AH , TocEntry * te );
9999static void processStdStringsEntry (ArchiveHandle * AH , TocEntry * te );
100100static teReqs _tocEntryRequired (TocEntry * te , RestoreOptions * ropt , bool include_acls );
101+ static bool _tocEntryIsACL (TocEntry * te );
101102static void _disableTriggersIfNecessary (ArchiveHandle * AH , TocEntry * te , RestoreOptions * ropt );
102103static void _enableTriggersIfNecessary (ArchiveHandle * AH , TocEntry * te , RestoreOptions * ropt );
103104static TocEntry * getTocEntryByDumpId (ArchiveHandle * AH , DumpId id );
@@ -329,9 +330,9 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
329330 AH -> currentTE = te ;
330331
331332 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 )
333335 {
334- /* We want the schema */
335336 ahlog (AH , 1 , "dropping %s %s\n" , te -> desc , te -> tag );
336337 /* Select owner and schema as necessary */
337338 _becomeOwner (AH , te );
@@ -381,7 +382,8 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
381382 /* Work out what, if anything, we want from this entry */
382383 reqs = _tocEntryRequired (te , ropt , true);
383384
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 )
385387 {
386388 ahlog (AH , 1 , "setting owner and privileges for %s %s\n" ,
387389 te -> desc , te -> tag );
@@ -905,6 +907,7 @@ EndRestoreBlobs(ArchiveHandle *AH)
905907void
906908StartRestoreBlob (ArchiveHandle * AH , Oid oid , bool drop )
907909{
910+ bool old_blob_style = (AH -> version < K_VERS_1_12 );
908911 Oid loOid ;
909912
910913 AH -> blobCount ++ ;
@@ -914,24 +917,32 @@ StartRestoreBlob(ArchiveHandle *AH, Oid oid, bool drop)
914917
915918 ahlog (AH , 2 , "restoring large object with OID %u\n" , oid );
916919
917- if (drop )
920+ /* With an old archive we must do drop and create logic here */
921+ if (old_blob_style && drop )
918922 DropBlobIfExists (AH , oid );
919923
920924 if (AH -> connection )
921925 {
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+ }
927933 AH -> loFd = lo_open (AH -> connection , oid , INV_WRITE );
928934 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 );
930937 }
931938 else
932939 {
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 );
935946 }
936947
937948 AH -> writingBlob = 1 ;
@@ -1829,6 +1840,9 @@ _allocAH(const char *FileSpec, const ArchiveFormat fmt,
18291840 AH -> vmin = K_VERS_MINOR ;
18301841 AH -> vrev = K_VERS_REV ;
18311842
1843+ /* Make a convenient integer <maj><min><rev>00 */
1844+ AH -> version = ((AH -> vmaj * 256 + AH -> vmin ) * 256 + AH -> vrev ) * 256 + 0 ;
1845+
18321846 /* initialize for backwards compatible string processing */
18331847 AH -> public .encoding = 0 ; /* PG_SQL_ASCII */
18341848 AH -> public .std_strings = false;
@@ -2068,12 +2082,13 @@ ReadToc(ArchiveHandle *AH)
20682082 else
20692083 {
20702084 /*
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.
20732088 */
20742089 if (strcmp (te -> desc , "COMMENT" ) == 0 ||
20752090 strcmp (te -> desc , "ACL" ) == 0 ||
2076- strcmp (te -> desc , "DEFAULT ACL" ) == 0 )
2091+ strcmp (te -> desc , "ACL LANGUAGE " ) == 0 )
20772092 te -> section = SECTION_NONE ;
20782093 else if (strcmp (te -> desc , "TABLE DATA" ) == 0 ||
20792094 strcmp (te -> desc , "BLOBS" ) == 0 ||
@@ -2228,10 +2243,10 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls)
22282243 return 0 ;
22292244
22302245 /* 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 ))
22332247 return 0 ;
22342248
2249+ /* Ignore DATABASE entry unless we should create it */
22352250 if (!ropt -> create && strcmp (te -> desc , "DATABASE" ) == 0 )
22362251 return 0 ;
22372252
@@ -2286,9 +2301,18 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls)
22862301 if (!te -> hadDumper )
22872302 {
22882303 /*
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.
22902309 */
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 ))
22922316 res = res & REQ_DATA ;
22932317 else
22942318 res = res & ~REQ_DATA ;
@@ -2320,6 +2344,20 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls)
23202344 return res ;
23212345}
23222346
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+
23232361/*
23242362 * Issue SET commands for parameters that we want to have set the same way
23252363 * at all times during execution of a restore script.
@@ -2685,6 +2723,13 @@ _getObjectDescription(PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH)
26852723 return ;
26862724 }
26872725
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+
26882733 /*
26892734 * These object types require additional decoration. Fortunately, the
26902735 * information needed is exactly what's in the DROP command.
@@ -2723,14 +2768,12 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
27232768 /* ACLs are dumped only during acl pass */
27242769 if (acl_pass )
27252770 {
2726- if (!(strcmp (te -> desc , "ACL" ) == 0 ||
2727- strcmp (te -> desc , "DEFAULT ACL" ) == 0 ))
2771+ if (!_tocEntryIsACL (te ))
27282772 return ;
27292773 }
27302774 else
27312775 {
2732- if (strcmp (te -> desc , "ACL" ) == 0 ||
2733- strcmp (te -> desc , "DEFAULT ACL" ) == 0 )
2776+ if (_tocEntryIsACL (te ))
27342777 return ;
27352778 }
27362779
@@ -2824,6 +2867,7 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
28242867 strlen (te -> owner ) > 0 && strlen (te -> dropStmt ) > 0 )
28252868 {
28262869 if (strcmp (te -> desc , "AGGREGATE" ) == 0 ||
2870+ strcmp (te -> desc , "BLOB" ) == 0 ||
28272871 strcmp (te -> desc , "CONVERSION" ) == 0 ||
28282872 strcmp (te -> desc , "DATABASE" ) == 0 ||
28292873 strcmp (te -> desc , "DOMAIN" ) == 0 ||
@@ -2873,7 +2917,7 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
28732917 * If it's an ACL entry, it might contain SET SESSION AUTHORIZATION
28742918 * commands, so we can no longer assume we know the current auth setting.
28752919 */
2876- if (strncmp ( te -> desc , "ACL" , 3 ) == 0 )
2920+ if (acl_pass )
28772921 {
28782922 if (AH -> currUser )
28792923 free (AH -> currUser );
0 commit comments