From: Tom Lane Date: Tue, 21 Jul 2009 21:46:10 +0000 (+0000) Subject: Make pg_dump/pg_restore --clean options drop large objects too. X-Git-Url: http://waps.l3s.uni-hannover.de/gitweb/?a=commitdiff_plain;h=1c1f2b82bb65539494492035c46b276639717438;p=users%2Fsimon%2Fpostgres.git Make pg_dump/pg_restore --clean options drop large objects too. In passing, make invocations of lo_xxx functions a bit more schema-safe. Itagaki Takahiro --- diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index e502825066..fe4841a94e 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -895,7 +895,7 @@ EndRestoreBlobs(ArchiveHandle *AH) * Called by a format handler to initiate restoration of a blob */ void -StartRestoreBlob(ArchiveHandle *AH, Oid oid) +StartRestoreBlob(ArchiveHandle *AH, Oid oid, bool drop) { Oid loOid; @@ -906,6 +906,10 @@ StartRestoreBlob(ArchiveHandle *AH, Oid oid) ahlog(AH, 2, "restoring large object with OID %u\n", oid); + if (drop) + ahprintf(AH, "SELECT CASE WHEN EXISTS(SELECT 1 FROM pg_catalog.pg_largeobject WHERE loid = '%u') THEN pg_catalog.lo_unlink('%u') END;\n", + oid, oid); + if (AH->connection) { loOid = lo_create(AH->connection, oid); @@ -919,7 +923,8 @@ StartRestoreBlob(ArchiveHandle *AH, Oid oid) } else { - ahprintf(AH, "SELECT lo_open(lo_create(%u), %d);\n", oid, INV_WRITE); + ahprintf(AH, "SELECT pg_catalog.lo_open(pg_catalog.lo_create('%u'), %d);\n", + oid, INV_WRITE); } AH->writingBlob = 1; @@ -943,7 +948,7 @@ EndRestoreBlob(ArchiveHandle *AH, Oid oid) } else { - ahprintf(AH, "SELECT lo_close(0);\n\n"); + ahprintf(AH, "SELECT pg_catalog.lo_close(0);\n\n"); } } @@ -1254,7 +1259,7 @@ dump_lo_buf(ArchiveHandle *AH) /* Hack: turn off writingBlob so ahwrite doesn't recurse to here */ AH->writingBlob = 0; - ahprintf(AH, "SELECT lowrite(0, '%s');\n", str); + ahprintf(AH, "SELECT pg_catalog.lowrite(0, '%s');\n", str); AH->writingBlob = 1; free(str); diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h index cd9d48c11f..5c779bdcef 100644 --- a/src/bin/pg_dump/pg_backup_archiver.h +++ b/src/bin/pg_dump/pg_backup_archiver.h @@ -355,7 +355,7 @@ int ReadOffset(ArchiveHandle *, pgoff_t *); size_t WriteOffset(ArchiveHandle *, pgoff_t, int); extern void StartRestoreBlobs(ArchiveHandle *AH); -extern void StartRestoreBlob(ArchiveHandle *AH, Oid oid); +extern void StartRestoreBlob(ArchiveHandle *AH, Oid oid, bool drop); extern void EndRestoreBlob(ArchiveHandle *AH, Oid oid); extern void EndRestoreBlobs(ArchiveHandle *AH); diff --git a/src/bin/pg_dump/pg_backup_custom.c b/src/bin/pg_dump/pg_backup_custom.c index 25ab8cd6ce..d2857250d1 100644 --- a/src/bin/pg_dump/pg_backup_custom.c +++ b/src/bin/pg_dump/pg_backup_custom.c @@ -54,7 +54,7 @@ static void _StartBlobs(ArchiveHandle *AH, TocEntry *te); static void _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid); static void _EndBlob(ArchiveHandle *AH, TocEntry *te, Oid oid); static void _EndBlobs(ArchiveHandle *AH, TocEntry *te); -static void _LoadBlobs(ArchiveHandle *AH); +static void _LoadBlobs(ArchiveHandle *AH, bool drop); static void _Clone(ArchiveHandle *AH); static void _DeClone(ArchiveHandle *AH); @@ -501,7 +501,7 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt) break; case BLK_BLOBS: - _LoadBlobs(AH); + _LoadBlobs(AH, ropt->dropSchema); break; default: /* Always have a default */ @@ -622,7 +622,7 @@ _PrintData(ArchiveHandle *AH) } static void -_LoadBlobs(ArchiveHandle *AH) +_LoadBlobs(ArchiveHandle *AH, bool drop) { Oid oid; @@ -631,7 +631,7 @@ _LoadBlobs(ArchiveHandle *AH) oid = ReadInt(AH); while (oid != 0) { - StartRestoreBlob(AH, oid); + StartRestoreBlob(AH, oid, drop); _PrintData(AH); EndRestoreBlob(AH, oid); oid = ReadInt(AH); diff --git a/src/bin/pg_dump/pg_backup_files.c b/src/bin/pg_dump/pg_backup_files.c index 8faa5e8db9..1faac0a491 100644 --- a/src/bin/pg_dump/pg_backup_files.c +++ b/src/bin/pg_dump/pg_backup_files.c @@ -382,7 +382,7 @@ _LoadBlobs(ArchiveHandle *AH, RestoreOptions *ropt) while (oid != 0) { - StartRestoreBlob(AH, oid); + StartRestoreBlob(AH, oid, ropt->dropSchema); _PrintFileData(AH, fname, ropt); EndRestoreBlob(AH, oid); _getBlobTocEntry(AH, &oid, fname); diff --git a/src/bin/pg_dump/pg_backup_null.c b/src/bin/pg_dump/pg_backup_null.c index 2baab210b2..2ae7351cc1 100644 --- a/src/bin/pg_dump/pg_backup_null.c +++ b/src/bin/pg_dump/pg_backup_null.c @@ -108,7 +108,7 @@ _WriteBlobData(ArchiveHandle *AH, const void *data, size_t dLen) if (!str) die_horribly(AH, NULL, "out of memory\n"); - ahprintf(AH, "SELECT lowrite(0, '%s');\n", str); + ahprintf(AH, "SELECT pg_catalog.lowrite(0, '%s');\n", str); free(str); } @@ -149,7 +149,12 @@ _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid) if (oid == 0) die_horribly(AH, NULL, "invalid OID for large object\n"); - ahprintf(AH, "SELECT lo_open(lo_create(%u), %d);\n", oid, INV_WRITE); + if (AH->ropt->dropSchema) + ahprintf(AH, "SELECT CASE WHEN EXISTS(SELECT 1 FROM pg_catalog.pg_largeobject WHERE loid = '%u') THEN pg_catalog.lo_unlink('%u') END;\n", + oid, oid); + + ahprintf(AH, "SELECT pg_catalog.lo_open(pg_catalog.lo_create('%u'), %d);\n", + oid, INV_WRITE); AH->WriteDataPtr = _WriteBlobData; } @@ -164,7 +169,7 @@ _EndBlob(ArchiveHandle *AH, TocEntry *te, Oid oid) { AH->WriteDataPtr = _WriteData; - ahprintf(AH, "SELECT lo_close(0);\n\n"); + ahprintf(AH, "SELECT pg_catalog.lo_close(0);\n\n"); } /* diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c index 0fab94e308..b5e0c43e88 100644 --- a/src/bin/pg_dump/pg_backup_tar.c +++ b/src/bin/pg_dump/pg_backup_tar.c @@ -729,7 +729,7 @@ _LoadBlobs(ArchiveHandle *AH, RestoreOptions *ropt) { ahlog(AH, 1, "restoring large object OID %u\n", oid); - StartRestoreBlob(AH, oid); + StartRestoreBlob(AH, oid, ropt->dropSchema); while ((cnt = tarRead(buf, 4095, th)) > 0) {