1 /*-------------------------------------------------------------------------
5 * Private implementation of the archiver routines.
7 * See the headers to pg_restore for more details.
9 * Copyright (c) 2000, Philip Warner
10 * Rights are granted to use this software in any way so long
11 * as this notice is not removed.
13 * The author is not responsible for loss or damages that may
14 * result from its use.
18 * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.129 2006/05/24 21:20:11 tgl Exp $
20 *-------------------------------------------------------------------------
23 #include "pg_backup.h"
25 #include "pg_backup_archiver.h"
26 #include "pg_backup_db.h"
27 #include "dumputils.h"
31 #ifndef WIN32_CLIENT_ONLY
39 #include "pqexpbuffer.h"
40 #include "libpq/libpq-fs.h"
45 static char *modulename = gettext_noop("archiver");
48 static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
49 const int compression, ArchiveMode mode);
50 static void _getObjectDescription(PQExpBuffer buf, TocEntry *te,
52 static void _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData, bool acl_pass);
55 static void _doSetFixedOutputState(ArchiveHandle *AH);
56 static void _doSetSessionAuth(ArchiveHandle *AH, const char *user);
57 static void _doSetWithOids(ArchiveHandle *AH, const bool withOids);
58 static void _reconnectToDB(ArchiveHandle *AH, const char *dbname);
59 static void _becomeUser(ArchiveHandle *AH, const char *user);
60 static void _becomeOwner(ArchiveHandle *AH, TocEntry *te);
61 static void _selectOutputSchema(ArchiveHandle *AH, const char *schemaName);
62 static void _selectTablespace(ArchiveHandle *AH, const char *tablespace);
64 static teReqs _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls);
65 static void _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
66 static void _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
67 static TocEntry *getTocEntryByDumpId(ArchiveHandle *AH, DumpId id);
68 static void _moveAfter(ArchiveHandle *AH, TocEntry *pos, TocEntry *te);
69 static int _discoverArchiveFormat(ArchiveHandle *AH);
71 static void dump_lo_buf(ArchiveHandle *AH);
72 static void _write_msg(const char *modulename, const char *fmt, va_list ap);
73 static void _die_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt, va_list ap);
75 static void dumpTimestamp(ArchiveHandle *AH, const char *msg, time_t tim);
81 * The objective it to make writing new formats and dumpers as simple
82 * as possible, if necessary at the expense of extra function calls etc.
87 /* Create a new archive */
90 CreateArchive(const char *FileSpec, const ArchiveFormat fmt,
91 const int compression)
94 ArchiveHandle *AH = _allocAH(FileSpec, fmt, compression, archModeWrite);
96 return (Archive *) AH;
99 /* Open an existing archive */
102 OpenArchive(const char *FileSpec, const ArchiveFormat fmt)
104 ArchiveHandle *AH = _allocAH(FileSpec, fmt, 0, archModeRead);
106 return (Archive *) AH;
111 CloseArchive(Archive *AHX)
114 ArchiveHandle *AH = (ArchiveHandle *) AHX;
116 (*AH->ClosePtr) (AH);
118 /* Close the output */
120 res = GZCLOSE(AH->OF);
121 else if (AH->OF != stdout)
122 res = fclose(AH->OF);
125 die_horribly(AH, modulename, "could not close output file: %s\n",
131 RestoreArchive(Archive *AHX, RestoreOptions *ropt)
133 ArchiveHandle *AH = (ArchiveHandle *) AHX;
140 AH->stage = STAGE_INITIALIZING;
143 * Check for nonsensical option combinations.
145 * NB: create+dropSchema is useless because if you're creating the DB,
146 * there's no need to drop individual items in it. Moreover, if we tried
147 * to do that then we'd issue the drops in the database initially
148 * connected to, not the one we will create, which is very bad...
150 if (ropt->create && ropt->dropSchema)
151 die_horribly(AH, modulename, "-C and -c are incompatible options\n");
154 * If we're using a DB connection, then connect it.
158 ahlog(AH, 1, "connecting to database for restore\n");
159 if (AH->version < K_VERS_1_3)
160 die_horribly(AH, modulename, "direct database connections are not supported in pre-1.3 archives\n");
162 /* XXX Should get this from the archive */
163 AHX->minRemoteVersion = 070100;
164 AHX->maxRemoteVersion = 999999;
166 ConnectDatabase(AHX, ropt->dbname,
167 ropt->pghost, ropt->pgport, ropt->username,
168 ropt->requirePassword, ropt->ignoreVersion);
171 * If we're talking to the DB directly, don't send comments since they
172 * obscure SQL when displaying errors
174 AH->noTocComments = 1;
178 * Work out if we have an implied data-only restore. This can happen if
179 * the dump was data only or if the user has used a toc list to exclude
180 * all of the schema data. All we do is look for schema entries - if none
181 * are found then we set the dataOnly flag.
183 * We could scan for wanted TABLE entries, but that is not the same as
184 * dataOnly. At this stage, it seems unnecessary (6-Mar-2001).
188 int impliedDataOnly = 1;
190 for (te = AH->toc->next; te != AH->toc; te = te->next)
192 reqs = _tocEntryRequired(te, ropt, true);
193 if ((reqs & REQ_SCHEMA) != 0)
194 { /* It's schema, and it's wanted */
201 ropt->dataOnly = impliedDataOnly;
202 ahlog(AH, 1, "implied data-only restore\n");
207 * Setup the output file if necessary.
209 if (ropt->filename || ropt->compression)
210 sav = SetOutput(AH, ropt->filename, ropt->compression);
212 ahprintf(AH, "--\n-- PostgreSQL database dump\n--\n\n");
214 if (AH->public.verbose)
215 dumpTimestamp(AH, "Started on", AH->createDate);
217 if (ropt->single_txn)
220 StartTransaction(AH);
222 ahprintf(AH, "BEGIN;\n\n");
226 * Establish important parameter values right away.
228 _doSetFixedOutputState(AH);
230 AH->stage = STAGE_PROCESSING;
233 * Drop the items at the start, in reverse order
235 if (ropt->dropSchema)
237 for (te = AH->toc->prev; te != AH->toc; te = te->prev)
241 reqs = _tocEntryRequired(te, ropt, false /* needn't drop ACLs */ );
242 if (((reqs & REQ_SCHEMA) != 0) && te->dropStmt)
244 /* We want the schema */
245 ahlog(AH, 1, "dropping %s %s\n", te->desc, te->tag);
246 /* Select owner and schema as necessary */
247 _becomeOwner(AH, te);
248 _selectOutputSchema(AH, te->namespace);
250 ahprintf(AH, "%s", te->dropStmt);
256 * Now process each non-ACL TOC entry
258 for (te = AH->toc->next; te != AH->toc; te = te->next)
262 /* Work out what, if anything, we want from this entry */
263 reqs = _tocEntryRequired(te, ropt, false);
265 /* Dump any relevant dump warnings to stderr */
266 if (!ropt->suppressDumpWarnings && strcmp(te->desc, "WARNING") == 0)
268 if (!ropt->dataOnly && te->defn != NULL && strlen(te->defn) != 0)
269 write_msg(modulename, "warning from original dump file: %s\n", te->defn);
270 else if (te->copyStmt != NULL && strlen(te->copyStmt) != 0)
271 write_msg(modulename, "warning from original dump file: %s\n", te->copyStmt);
276 if ((reqs & REQ_SCHEMA) != 0) /* We want the schema */
278 ahlog(AH, 1, "creating %s %s\n", te->desc, te->tag);
280 _printTocEntry(AH, te, ropt, false, false);
283 /* If we created a DB, connect to it... */
284 if (strcmp(te->desc, "DATABASE") == 0)
286 ahlog(AH, 1, "connecting to new database \"%s\"\n", te->tag);
287 _reconnectToDB(AH, te->tag);
292 * If we have a data component, then process it
294 if ((reqs & REQ_DATA) != 0)
297 * hadDumper will be set if there is genuine data component for
298 * this node. Otherwise, we need to check the defn field for
299 * statements that need to be executed in data-only restores.
304 * If we can output the data, then restore it.
306 if (AH->PrintTocDataPtr !=NULL && (reqs & REQ_DATA) != 0)
309 if (AH->compression != 0)
310 die_horribly(AH, modulename, "cannot restore from compressed archive (compression not supported in this installation)\n");
313 _printTocEntry(AH, te, ropt, true, false);
315 if (strcmp(te->desc, "BLOBS") == 0 ||
316 strcmp(te->desc, "BLOB COMMENTS") == 0)
318 ahlog(AH, 1, "restoring %s\n", te->desc);
320 _selectOutputSchema(AH, "pg_catalog");
322 (*AH->PrintTocDataPtr) (AH, te, ropt);
326 _disableTriggersIfNecessary(AH, te, ropt);
328 /* Select owner and schema as necessary */
329 _becomeOwner(AH, te);
330 _selectOutputSchema(AH, te->namespace);
332 ahlog(AH, 1, "restoring data for table \"%s\"\n",
336 * If we have a copy statement, use it. As of V1.3,
337 * these are separate to allow easy import from
338 * withing a database connection. Pre 1.3 archives can
339 * not use DB connections and are sent to output only.
341 * For V1.3+, the table data MUST have a copy
342 * statement so that we can go into appropriate mode
345 if (te->copyStmt && strlen(te->copyStmt) > 0)
347 ahprintf(AH, "%s", te->copyStmt);
348 AH->writingCopyData = true;
351 (*AH->PrintTocDataPtr) (AH, te, ropt);
353 AH->writingCopyData = false;
355 _enableTriggersIfNecessary(AH, te, ropt);
359 else if (!defnDumped)
361 /* If we haven't already dumped the defn part, do so now */
362 ahlog(AH, 1, "executing %s %s\n", te->desc, te->tag);
363 _printTocEntry(AH, te, ropt, false, false);
366 } /* end loop over TOC entries */
369 * Scan TOC again to output ownership commands and ACLs
371 for (te = AH->toc->next; te != AH->toc; te = te->next)
375 /* Work out what, if anything, we want from this entry */
376 reqs = _tocEntryRequired(te, ropt, true);
378 if ((reqs & REQ_SCHEMA) != 0) /* We want the schema */
380 ahlog(AH, 1, "setting owner and privileges for %s %s\n",
382 _printTocEntry(AH, te, ropt, false, true);
386 if (ropt->single_txn)
389 CommitTransaction(AH);
391 ahprintf(AH, "COMMIT;\n\n");
394 if (AH->public.verbose)
395 dumpTimestamp(AH, "Completed on", time(NULL));
397 ahprintf(AH, "--\n-- PostgreSQL database dump complete\n--\n\n");
400 * Clean up & we're done.
402 AH->stage = STAGE_FINALIZING;
404 if (ropt->filename || ropt->compression)
405 ResetOutput(AH, sav);
409 PQfinish(AH->connection);
410 AH->connection = NULL;
415 * Allocate a new RestoreOptions block.
416 * This is mainly so we can initialize it, but also for future expansion,
419 NewRestoreOptions(void)
421 RestoreOptions *opts;
423 opts = (RestoreOptions *) calloc(1, sizeof(RestoreOptions));
425 opts->format = archUnknown;
426 opts->suppressDumpWarnings = false;
427 opts->exit_on_error = false;
433 _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
435 /* This hack is only needed in a data-only restore */
436 if (!ropt->dataOnly || !ropt->disable_triggers)
439 ahlog(AH, 1, "disabling triggers for %s\n", te->tag);
442 * Become superuser if possible, since they are the only ones who can
443 * disable constraint triggers. If -S was not given, assume the initial
444 * user identity is a superuser. (XXX would it be better to become the
447 _becomeUser(AH, ropt->superuser);
452 _selectOutputSchema(AH, te->namespace);
454 ahprintf(AH, "ALTER TABLE %s DISABLE TRIGGER ALL;\n\n",
459 _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
461 /* This hack is only needed in a data-only restore */
462 if (!ropt->dataOnly || !ropt->disable_triggers)
465 ahlog(AH, 1, "enabling triggers for %s\n", te->tag);
468 * Become superuser if possible, since they are the only ones who can
469 * disable constraint triggers. If -S was not given, assume the initial
470 * user identity is a superuser. (XXX would it be better to become the
473 _becomeUser(AH, ropt->superuser);
478 _selectOutputSchema(AH, te->namespace);
480 ahprintf(AH, "ALTER TABLE %s ENABLE TRIGGER ALL;\n\n",
485 * This is a routine that is part of the dumper interface, hence the 'Archive*' parameter.
490 WriteData(Archive *AHX, const void *data, size_t dLen)
492 ArchiveHandle *AH = (ArchiveHandle *) AHX;
495 die_horribly(AH, modulename, "internal error -- WriteData cannot be called outside the context of a DataDumper routine\n");
497 return (*AH->WriteDataPtr) (AH, data, dLen);
501 * Create a new TOC entry. The TOC was designed as a TOC, but is now the
502 * repository for all metadata. But the name has stuck.
507 ArchiveEntry(Archive *AHX,
508 CatalogId catalogId, DumpId dumpId,
510 const char *namespace,
511 const char *tablespace,
512 const char *owner, bool withOids,
513 const char *desc, const char *defn,
514 const char *dropStmt, const char *copyStmt,
515 const DumpId *deps, int nDeps,
516 DataDumperPtr dumpFn, void *dumpArg)
518 ArchiveHandle *AH = (ArchiveHandle *) AHX;
521 newToc = (TocEntry *) calloc(1, sizeof(TocEntry));
523 die_horribly(AH, modulename, "out of memory\n");
526 if (dumpId > AH->maxDumpId)
527 AH->maxDumpId = dumpId;
529 newToc->prev = AH->toc->prev;
530 newToc->next = AH->toc;
531 AH->toc->prev->next = newToc;
532 AH->toc->prev = newToc;
534 newToc->catalogId = catalogId;
535 newToc->dumpId = dumpId;
537 newToc->tag = strdup(tag);
538 newToc->namespace = namespace ? strdup(namespace) : NULL;
539 newToc->tablespace = tablespace ? strdup(tablespace) : NULL;
540 newToc->owner = strdup(owner);
541 newToc->withOids = withOids;
542 newToc->desc = strdup(desc);
543 newToc->defn = strdup(defn);
544 newToc->dropStmt = strdup(dropStmt);
545 newToc->copyStmt = copyStmt ? strdup(copyStmt) : NULL;
549 newToc->dependencies = (DumpId *) malloc(nDeps * sizeof(DumpId));
550 memcpy(newToc->dependencies, deps, nDeps * sizeof(DumpId));
551 newToc->nDeps = nDeps;
555 newToc->dependencies = NULL;
559 newToc->dataDumper = dumpFn;
560 newToc->dataDumperArg = dumpArg;
561 newToc->hadDumper = dumpFn ? true : false;
563 newToc->formatData = NULL;
565 if (AH->ArchiveEntryPtr !=NULL)
566 (*AH->ArchiveEntryPtr) (AH, newToc);
571 PrintTOCSummary(Archive *AHX, RestoreOptions *ropt)
573 ArchiveHandle *AH = (ArchiveHandle *) AHX;
574 TocEntry *te = AH->toc->next;
579 sav = SetOutput(AH, ropt->filename, 0 /* no compression */ );
581 ahprintf(AH, ";\n; Archive created at %s", ctime(&AH->createDate));
582 ahprintf(AH, "; dbname: %s\n; TOC Entries: %d\n; Compression: %d\n",
583 AH->archdbname, AH->tocCount, AH->compression);
600 ahprintf(AH, "; Dump Version: %d.%d-%d\n", AH->vmaj, AH->vmin, AH->vrev);
601 ahprintf(AH, "; Format: %s\n", fmtName);
602 ahprintf(AH, "; Integer: %d bytes\n", (int) AH->intSize);
603 ahprintf(AH, "; Offset: %d bytes\n", (int) AH->offSize);
604 if (AH->archiveRemoteVersion)
605 ahprintf(AH, "; Dumped from database version: %s\n",
606 AH->archiveRemoteVersion);
607 if (AH->archiveDumpVersion)
608 ahprintf(AH, "; Dumped by pg_dump version: %s\n",
609 AH->archiveDumpVersion);
611 ahprintf(AH, ";\n;\n; Selected TOC Entries:\n;\n");
613 while (te != AH->toc)
615 if (_tocEntryRequired(te, ropt, true) != 0)
616 ahprintf(AH, "%d; %u %u %s %s %s %s\n", te->dumpId,
617 te->catalogId.tableoid, te->catalogId.oid,
618 te->desc, te->namespace ? te->namespace : "-",
624 ResetOutput(AH, sav);
631 /* Called by a dumper to signal start of a BLOB */
633 StartBlob(Archive *AHX, Oid oid)
635 ArchiveHandle *AH = (ArchiveHandle *) AHX;
637 if (!AH->StartBlobPtr)
638 die_horribly(AH, modulename, "large-object output not supported in chosen format\n");
640 (*AH->StartBlobPtr) (AH, AH->currToc, oid);
645 /* Called by a dumper to signal end of a BLOB */
647 EndBlob(Archive *AHX, Oid oid)
649 ArchiveHandle *AH = (ArchiveHandle *) AHX;
652 (*AH->EndBlobPtr) (AH, AH->currToc, oid);
662 * Called by a format handler before any blobs are restored
665 StartRestoreBlobs(ArchiveHandle *AH)
667 if (!AH->ropt->single_txn)
670 StartTransaction(AH);
672 ahprintf(AH, "BEGIN;\n\n");
679 * Called by a format handler after all blobs are restored
682 EndRestoreBlobs(ArchiveHandle *AH)
684 if (!AH->ropt->single_txn)
687 CommitTransaction(AH);
689 ahprintf(AH, "COMMIT;\n\n");
692 ahlog(AH, 1, "restored %d large objects\n", AH->blobCount);
697 * Called by a format handler to initiate restoration of a blob
700 StartRestoreBlob(ArchiveHandle *AH, Oid oid)
706 /* Initialize the LO Buffer */
709 ahlog(AH, 2, "restoring large object with OID %u\n", oid);
713 loOid = lo_create(AH->connection, oid);
714 if (loOid == 0 || loOid != oid)
715 die_horribly(AH, modulename, "could not create large object %u\n",
718 AH->loFd = lo_open(AH->connection, oid, INV_WRITE);
720 die_horribly(AH, modulename, "could not open large object\n");
724 ahprintf(AH, "SELECT lo_open(lo_create(%u), %d);\n", oid, INV_WRITE);
731 EndRestoreBlob(ArchiveHandle *AH, Oid oid)
733 if (AH->lo_buf_used > 0)
735 /* Write remaining bytes from the LO buffer */
743 lo_close(AH->connection, AH->loFd);
748 ahprintf(AH, "SELECT lo_close(0);\n\n");
753 * Sorting and Reordering
757 SortTocFromFile(Archive *AHX, RestoreOptions *ropt)
759 ArchiveHandle *AH = (ArchiveHandle *) AHX;
768 /* Allocate space for the 'wanted' array, and init it */
769 ropt->idWanted = (bool *) malloc(sizeof(bool) * AH->maxDumpId);
770 memset(ropt->idWanted, 0, sizeof(bool) * AH->maxDumpId);
771 ropt->limitToList = true;
773 /* Set prev entry as head of list */
777 fh = fopen(ropt->tocFile, PG_BINARY_R);
779 die_horribly(AH, modulename, "could not open TOC file: %s\n",
782 while (fgets(buf, sizeof(buf), fh) != NULL)
784 /* Truncate line at comment, if any */
785 cmnt = strchr(buf, ';');
789 /* Ignore if all blank */
790 if (strspn(buf, " \t\r") == strlen(buf))
793 /* Get an ID, check it's valid and not already seen */
794 id = strtol(buf, &endptr, 10);
795 if (endptr == buf || id <= 0 || id > AH->maxDumpId ||
796 ropt->idWanted[id - 1])
798 write_msg(modulename, "WARNING: line ignored: %s\n", buf);
803 te = getTocEntryByDumpId(AH, id);
805 die_horribly(AH, modulename, "could not find entry for ID %d\n",
808 ropt->idWanted[id - 1] = true;
810 _moveAfter(AH, tePrev, te);
815 die_horribly(AH, modulename, "could not close TOC file: %s\n",
819 /**********************
820 * 'Convenience functions that look like standard IO functions
821 * for writing data when in dump mode.
822 **********************/
826 archputs(const char *s, Archive *AH)
828 return WriteData(AH, s, strlen(s));
833 archprintf(Archive *AH, const char *fmt,...)
837 int bSize = strlen(fmt) + 256;
841 * This is paranoid: deal with the possibility that vsnprintf is willing
842 * to ignore trailing null or returns > 0 even if string does not fit. It
843 * may be the case that it returns cnt = bufsize
845 while (cnt < 0 || cnt >= (bSize - 1))
850 p = (char *) malloc(bSize);
852 exit_horribly(AH, modulename, "out of memory\n");
854 cnt = vsnprintf(p, bSize, fmt, ap);
857 WriteData(AH, p, cnt);
863 /*******************************
864 * Stuff below here should be 'private' to the archiver routines
865 *******************************/
868 SetOutput(ArchiveHandle *AH, char *filename, int compression)
873 /* Replace the AH output file handle */
875 sav.gzOut = AH->gzOut;
884 filename = AH->fSpec;
889 /* If compression explicitly requested, use gzopen */
891 if (compression != 0)
895 /* Don't use PG_BINARY_x since this is zlib */
896 sprintf(fmode, "wb%d", compression);
898 AH->OF = gzdopen(dup(fn), fmode);
900 AH->OF = gzopen(filename, fmode);
907 AH->OF = fdopen(dup(fn), PG_BINARY_W);
909 AH->OF = fopen(filename, PG_BINARY_W);
914 die_horribly(AH, modulename, "could not open output file: %s\n", strerror(errno));
920 ResetOutput(ArchiveHandle *AH, OutputContext sav)
925 res = GZCLOSE(AH->OF);
927 res = fclose(AH->OF);
930 die_horribly(AH, modulename, "could not close output file: %s\n",
933 AH->gzOut = sav.gzOut;
940 * Print formatted text to the output file (usually stdout).
943 ahprintf(ArchiveHandle *AH, const char *fmt,...)
947 int bSize = strlen(fmt) + 256; /* Should be enough */
951 * This is paranoid: deal with the possibility that vsnprintf is willing
952 * to ignore trailing null
956 * or returns > 0 even if string does not fit. It may be the case that it
957 * returns cnt = bufsize
959 while (cnt < 0 || cnt >= (bSize - 1))
964 p = (char *) malloc(bSize);
966 die_horribly(AH, modulename, "out of memory\n");
968 cnt = vsnprintf(p, bSize, fmt, ap);
971 ahwrite(p, 1, cnt, AH);
977 ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
981 if (AH->debugLevel < level && (!AH->public.verbose || level > 1))
985 _write_msg(NULL, fmt, ap);
990 * Single place for logic which says 'We are restoring to a direct DB connection'.
993 RestoringToDB(ArchiveHandle *AH)
995 return (AH->ropt && AH->ropt->useDB && AH->connection);
999 * Dump the current contents of the LO data buffer while writing a BLOB
1002 dump_lo_buf(ArchiveHandle *AH)
1008 res = lo_write(AH->connection, AH->loFd, AH->lo_buf, AH->lo_buf_used);
1009 ahlog(AH, 5, "wrote %lu bytes of large object data (result = %lu)\n",
1010 (unsigned long) AH->lo_buf_used, (unsigned long) res);
1011 if (res != AH->lo_buf_used)
1012 die_horribly(AH, modulename,
1013 "could not write to large object (result: %lu, expected: %lu)\n",
1014 (unsigned long) res, (unsigned long) AH->lo_buf_used);
1021 str = PQescapeBytea((const unsigned char *) AH->lo_buf,
1022 AH->lo_buf_used, &len);
1024 die_horribly(AH, modulename, "out of memory\n");
1026 /* Hack: turn off writingBlob so ahwrite doesn't recurse to here */
1027 AH->writingBlob = 0;
1028 ahprintf(AH, "SELECT lowrite(0, '%s');\n", str);
1029 AH->writingBlob = 1;
1033 AH->lo_buf_used = 0;
1038 * Write buffer to the output file (usually stdout). This is user for
1039 * outputting 'restore' scripts etc. It is even possible for an archive
1040 * format to create a custom output routine to 'fake' a restore if it
1041 * wants to generate a script (see TAR output).
1044 ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
1048 if (AH->writingBlob)
1050 size_t remaining = size * nmemb;
1052 while (AH->lo_buf_used + remaining > AH->lo_buf_size)
1054 size_t avail = AH->lo_buf_size - AH->lo_buf_used;
1056 memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, avail);
1057 ptr = (const void *) ((const char *) ptr + avail);
1059 AH->lo_buf_used += avail;
1063 memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, remaining);
1064 AH->lo_buf_used += remaining;
1066 return size * nmemb;
1070 res = GZWRITE((void *) ptr, size, nmemb, AH->OF);
1071 if (res != (nmemb * size))
1072 die_horribly(AH, modulename, "could not write to output file: %s\n", strerror(errno));
1075 else if (AH->CustomOutPtr)
1077 res = AH->CustomOutPtr (AH, ptr, size * nmemb);
1079 if (res != (nmemb * size))
1080 die_horribly(AH, modulename, "could not write to custom output routine\n");
1086 * If we're doing a restore, and it's direct to DB, and we're
1087 * connected then send it to the DB.
1089 if (RestoringToDB(AH))
1090 return ExecuteSqlCommandBuf(AH, (void *) ptr, size * nmemb); /* Always 1, currently */
1093 res = fwrite((void *) ptr, size, nmemb, AH->OF);
1095 die_horribly(AH, modulename, "could not write to output file: %s\n",
1102 /* Common exit code */
1104 _write_msg(const char *modulename, const char *fmt, va_list ap)
1107 fprintf(stderr, "%s: [%s] ", progname, _(modulename));
1109 fprintf(stderr, "%s: ", progname);
1110 vfprintf(stderr, _(fmt), ap);
1114 write_msg(const char *modulename, const char *fmt,...)
1119 _write_msg(modulename, fmt, ap);
1125 _die_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt, va_list ap)
1127 _write_msg(modulename, fmt, ap);
1131 if (AH->public.verbose)
1132 write_msg(NULL, "*** aborted because of error\n");
1134 PQfinish(AH->connection);
1142 exit_horribly(Archive *AH, const char *modulename, const char *fmt,...)
1147 _die_horribly((ArchiveHandle *) AH, modulename, fmt, ap);
1151 /* Archiver use (just different arg declaration) */
1153 die_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt,...)
1158 _die_horribly(AH, modulename, fmt, ap);
1162 /* on some error, we may decide to go on... */
1164 warn_or_die_horribly(ArchiveHandle *AH,
1165 const char *modulename, const char *fmt,...)
1173 /* Do nothing special */
1176 case STAGE_INITIALIZING:
1177 if (AH->stage != AH->lastErrorStage)
1178 write_msg(modulename, "Error while INITIALIZING:\n");
1181 case STAGE_PROCESSING:
1182 if (AH->stage != AH->lastErrorStage)
1183 write_msg(modulename, "Error while PROCESSING TOC:\n");
1186 case STAGE_FINALIZING:
1187 if (AH->stage != AH->lastErrorStage)
1188 write_msg(modulename, "Error while FINALIZING:\n");
1191 if (AH->currentTE != NULL && AH->currentTE != AH->lastErrorTE)
1193 write_msg(modulename, "Error from TOC entry %d; %u %u %s %s %s\n",
1194 AH->currentTE->dumpId,
1195 AH->currentTE->catalogId.tableoid, AH->currentTE->catalogId.oid,
1196 AH->currentTE->desc, AH->currentTE->tag, AH->currentTE->owner);
1198 AH->lastErrorStage = AH->stage;
1199 AH->lastErrorTE = AH->currentTE;
1202 if (AH->public.exit_on_error)
1203 _die_horribly(AH, modulename, fmt, ap);
1206 _write_msg(modulename, fmt, ap);
1207 AH->public.n_errors++;
1213 _moveAfter(ArchiveHandle *AH, TocEntry *pos, TocEntry *te)
1215 te->prev->next = te->next;
1216 te->next->prev = te->prev;
1219 te->next = pos->next;
1221 pos->next->prev = te;
1228 _moveBefore(ArchiveHandle *AH, TocEntry *pos, TocEntry *te)
1230 te->prev->next = te->next;
1231 te->next->prev = te->prev;
1233 te->prev = pos->prev;
1235 pos->prev->next = te;
1241 getTocEntryByDumpId(ArchiveHandle *AH, DumpId id)
1246 while (te != AH->toc)
1248 if (te->dumpId == id)
1256 TocIDRequired(ArchiveHandle *AH, DumpId id, RestoreOptions *ropt)
1258 TocEntry *te = getTocEntryByDumpId(AH, id);
1263 return _tocEntryRequired(te, ropt, true);
1267 WriteOffset(ArchiveHandle *AH, off_t o, int wasSet)
1272 (*AH->WriteBytePtr) (AH, wasSet);
1274 /* Write out off_t smallest byte first, prevents endian mismatch */
1275 for (off = 0; off < sizeof(off_t); off++)
1277 (*AH->WriteBytePtr) (AH, o & 0xFF);
1280 return sizeof(off_t) + 1;
1284 ReadOffset(ArchiveHandle *AH, off_t *o)
1290 /* Initialize to zero */
1293 /* Check for old version */
1294 if (AH->version < K_VERS_1_7)
1296 /* Prior versions wrote offsets using WriteInt */
1298 /* -1 means not set */
1300 return K_OFFSET_POS_NOT_SET;
1302 return K_OFFSET_NO_DATA;
1304 /* Cast to off_t because it was written as an int. */
1306 return K_OFFSET_POS_SET;
1310 * Read the flag indicating the state of the data pointer. Check if valid
1313 * This used to be handled by a negative or zero pointer, now we use an
1314 * extra byte specifically for the state.
1316 offsetFlg = (*AH->ReadBytePtr) (AH) & 0xFF;
1320 case K_OFFSET_POS_NOT_SET:
1321 case K_OFFSET_NO_DATA:
1322 case K_OFFSET_POS_SET:
1327 die_horribly(AH, modulename, "unexpected data offset flag %d\n", offsetFlg);
1333 for (off = 0; off < AH->offSize; off++)
1335 if (off < sizeof(off_t))
1336 *o |= ((off_t) ((*AH->ReadBytePtr) (AH))) << (off * 8);
1339 if ((*AH->ReadBytePtr) (AH) != 0)
1340 die_horribly(AH, modulename, "file offset in dump file is too large\n");
1348 WriteInt(ArchiveHandle *AH, int i)
1353 * This is a bit yucky, but I don't want to make the binary format very
1354 * dependent on representation, and not knowing much about it, I write out
1355 * a sign byte. If you change this, don't forget to change the file
1356 * version #, and modify readInt to read the new format AS WELL AS the old
1363 (*AH->WriteBytePtr) (AH, 1);
1367 (*AH->WriteBytePtr) (AH, 0);
1369 for (b = 0; b < AH->intSize; b++)
1371 (*AH->WriteBytePtr) (AH, i & 0xFF);
1375 return AH->intSize + 1;
1379 ReadInt(ArchiveHandle *AH)
1384 int sign = 0; /* Default positive */
1387 if (AH->version > K_VERS_1_0)
1388 /* Read a sign byte */
1389 sign = (*AH->ReadBytePtr) (AH);
1391 for (b = 0; b < AH->intSize; b++)
1393 bv = (*AH->ReadBytePtr) (AH) & 0xFF;
1395 res = res + (bv << bitShift);
1406 WriteStr(ArchiveHandle *AH, const char *c)
1412 res = WriteInt(AH, strlen(c));
1413 res += (*AH->WriteBufPtr) (AH, c, strlen(c));
1416 res = WriteInt(AH, -1);
1422 ReadStr(ArchiveHandle *AH)
1432 buf = (char *) malloc(l + 1);
1434 die_horribly(AH, modulename, "out of memory\n");
1436 (*AH->ReadBufPtr) (AH, (void *) buf, l);
1444 _discoverArchiveFormat(ArchiveHandle *AH)
1447 char sig[6]; /* More than enough */
1452 write_msg(modulename, "attempting to ascertain archive format\n");
1456 free(AH->lookahead);
1458 AH->lookaheadSize = 512;
1459 AH->lookahead = calloc(1, 512);
1460 AH->lookaheadLen = 0;
1461 AH->lookaheadPos = 0;
1466 fh = fopen(AH->fSpec, PG_BINARY_R);
1472 die_horribly(AH, modulename, "could not open input file: %s\n", strerror(errno));
1474 cnt = fread(sig, 1, 5, fh);
1479 die_horribly(AH, modulename, "could not read input file: %s\n", strerror(errno));
1481 die_horribly(AH, modulename, "input file is too short (read %lu, expected 5)\n",
1482 (unsigned long) cnt);
1485 /* Save it, just in case we need it later */
1486 strncpy(&AH->lookahead[0], sig, 5);
1487 AH->lookaheadLen = 5;
1489 if (strncmp(sig, "PGDMP", 5) == 0)
1491 AH->vmaj = fgetc(fh);
1492 AH->vmin = fgetc(fh);
1494 /* Save these too... */
1495 AH->lookahead[AH->lookaheadLen++] = AH->vmaj;
1496 AH->lookahead[AH->lookaheadLen++] = AH->vmin;
1498 /* Check header version; varies from V1.0 */
1499 if (AH->vmaj > 1 || ((AH->vmaj == 1) && (AH->vmin > 0))) /* Version > 1.0 */
1501 AH->vrev = fgetc(fh);
1502 AH->lookahead[AH->lookaheadLen++] = AH->vrev;
1507 /* Make a convenient integer <maj><min><rev>00 */
1508 AH->version = ((AH->vmaj * 256 + AH->vmin) * 256 + AH->vrev) * 256 + 0;
1510 AH->intSize = fgetc(fh);
1511 AH->lookahead[AH->lookaheadLen++] = AH->intSize;
1513 if (AH->version >= K_VERS_1_7)
1515 AH->offSize = fgetc(fh);
1516 AH->lookahead[AH->lookaheadLen++] = AH->offSize;
1519 AH->offSize = AH->intSize;
1521 AH->format = fgetc(fh);
1522 AH->lookahead[AH->lookaheadLen++] = AH->format;
1527 * *Maybe* we have a tar archive format file... So, read first 512
1530 cnt = fread(&AH->lookahead[AH->lookaheadLen], 1, 512 - AH->lookaheadLen, fh);
1531 AH->lookaheadLen += cnt;
1533 if (AH->lookaheadLen != 512)
1534 die_horribly(AH, modulename, "input file does not appear to be a valid archive (too short?)\n");
1536 if (!isValidTarHeader(AH->lookahead))
1537 die_horribly(AH, modulename, "input file does not appear to be a valid archive\n");
1539 AH->format = archTar;
1542 /* If we can't seek, then mark the header as read */
1543 if (fseeko(fh, 0, SEEK_SET) != 0)
1546 * NOTE: Formats that use the lookahead buffer can unset this in their
1552 AH->lookaheadLen = 0; /* Don't bother since we've reset the file */
1555 write_msg(modulename, "read %lu bytes into lookahead buffer\n",
1556 (unsigned long) AH->lookaheadLen);
1559 /* Close the file */
1561 if (fclose(fh) != 0)
1562 die_horribly(AH, modulename, "could not close input file: %s\n",
1570 * Allocate an archive handle
1572 static ArchiveHandle *
1573 _allocAH(const char *FileSpec, const ArchiveFormat fmt,
1574 const int compression, ArchiveMode mode)
1579 write_msg(modulename, "allocating AH for %s, format %d\n", FileSpec, fmt);
1582 AH = (ArchiveHandle *) calloc(1, sizeof(ArchiveHandle));
1584 die_horribly(AH, modulename, "out of memory\n");
1586 /* AH->debugLevel = 100; */
1588 AH->vmaj = K_VERS_MAJOR;
1589 AH->vmin = K_VERS_MINOR;
1590 AH->vrev = K_VERS_REV;
1592 AH->createDate = time(NULL);
1594 AH->intSize = sizeof(int);
1595 AH->offSize = sizeof(off_t);
1598 AH->fSpec = strdup(FileSpec);
1601 * Not used; maybe later....
1603 * AH->workDir = strdup(FileSpec); for(i=strlen(FileSpec) ; i > 0 ;
1604 * i--) if (AH->workDir[i-1] == '/')
1610 AH->currUser = strdup(""); /* So it's valid, but we can free() it later
1612 AH->currSchema = strdup(""); /* ditto */
1613 AH->currWithOids = -1; /* force SET */
1615 AH->toc = (TocEntry *) calloc(1, sizeof(TocEntry));
1617 die_horribly(AH, modulename, "out of memory\n");
1619 AH->toc->next = AH->toc;
1620 AH->toc->prev = AH->toc;
1623 AH->compression = compression;
1625 AH->pgCopyBuf = createPQExpBuffer();
1626 AH->sqlBuf = createPQExpBuffer();
1628 /* Open stdout with no compression for AH output handle */
1633 * On Windows, we need to use binary mode to read/write non-text archive
1634 * formats. Force stdin/stdout into binary mode if that is what we are
1638 if (fmt != archNull &&
1639 (AH->fSpec == NULL || strcmp(AH->fSpec, "") == 0))
1641 if (mode == archModeWrite)
1642 setmode(fileno(stdout), O_BINARY);
1644 setmode(fileno(stdin), O_BINARY);
1649 write_msg(modulename, "archive format is %d\n", fmt);
1652 if (fmt == archUnknown)
1653 AH->format = _discoverArchiveFormat(AH);
1660 InitArchiveFmt_Custom(AH);
1664 InitArchiveFmt_Files(AH);
1668 InitArchiveFmt_Null(AH);
1672 InitArchiveFmt_Tar(AH);
1676 die_horribly(AH, modulename, "unrecognized file format \"%d\"\n", fmt);
1679 /* sql error handling */
1680 AH->public.exit_on_error = true;
1681 AH->public.n_errors = 0;
1688 WriteDataChunks(ArchiveHandle *AH)
1690 TocEntry *te = AH->toc->next;
1691 StartDataPtr startPtr;
1694 while (te != AH->toc)
1696 if (te->dataDumper != NULL)
1699 /* printf("Writing data for %d (%x)\n", te->id, te); */
1701 if (strcmp(te->desc, "BLOBS") == 0)
1703 startPtr = AH->StartBlobsPtr;
1704 endPtr = AH->EndBlobsPtr;
1708 startPtr = AH->StartDataPtr;
1709 endPtr = AH->EndDataPtr;
1712 if (startPtr != NULL)
1713 (*startPtr) (AH, te);
1716 * printf("Dumper arg for %d is %x\n", te->id, te->dataDumperArg);
1720 * The user-provided DataDumper routine needs to call
1723 (*te->dataDumper) ((Archive *) AH, te->dataDumperArg);
1734 WriteToc(ArchiveHandle *AH)
1740 /* printf("%d TOC Entries to save\n", AH->tocCount); */
1742 WriteInt(AH, AH->tocCount);
1744 for (te = AH->toc->next; te != AH->toc; te = te->next)
1746 WriteInt(AH, te->dumpId);
1747 WriteInt(AH, te->dataDumper ? 1 : 0);
1749 /* OID is recorded as a string for historical reasons */
1750 sprintf(workbuf, "%u", te->catalogId.tableoid);
1751 WriteStr(AH, workbuf);
1752 sprintf(workbuf, "%u", te->catalogId.oid);
1753 WriteStr(AH, workbuf);
1755 WriteStr(AH, te->tag);
1756 WriteStr(AH, te->desc);
1757 WriteStr(AH, te->defn);
1758 WriteStr(AH, te->dropStmt);
1759 WriteStr(AH, te->copyStmt);
1760 WriteStr(AH, te->namespace);
1761 WriteStr(AH, te->tablespace);
1762 WriteStr(AH, te->owner);
1763 WriteStr(AH, te->withOids ? "true" : "false");
1765 /* Dump list of dependencies */
1766 for (i = 0; i < te->nDeps; i++)
1768 sprintf(workbuf, "%d", te->dependencies[i]);
1769 WriteStr(AH, workbuf);
1771 WriteStr(AH, NULL); /* Terminate List */
1773 if (AH->WriteExtraTocPtr)
1774 (*AH->WriteExtraTocPtr) (AH, te);
1779 ReadToc(ArchiveHandle *AH)
1787 TocEntry *te = AH->toc->next;
1789 AH->tocCount = ReadInt(AH);
1792 for (i = 0; i < AH->tocCount; i++)
1794 te = (TocEntry *) calloc(1, sizeof(TocEntry));
1795 te->dumpId = ReadInt(AH);
1797 if (te->dumpId > AH->maxDumpId)
1798 AH->maxDumpId = te->dumpId;
1801 if (te->dumpId <= 0)
1802 die_horribly(AH, modulename,
1803 "entry ID %d out of range -- perhaps a corrupt TOC\n",
1806 te->hadDumper = ReadInt(AH);
1808 if (AH->version >= K_VERS_1_8)
1811 sscanf(tmp, "%u", &te->catalogId.tableoid);
1815 te->catalogId.tableoid = InvalidOid;
1817 sscanf(tmp, "%u", &te->catalogId.oid);
1820 te->tag = ReadStr(AH);
1821 te->desc = ReadStr(AH);
1822 te->defn = ReadStr(AH);
1823 te->dropStmt = ReadStr(AH);
1825 if (AH->version >= K_VERS_1_3)
1826 te->copyStmt = ReadStr(AH);
1828 if (AH->version >= K_VERS_1_6)
1829 te->namespace = ReadStr(AH);
1831 if (AH->version >= K_VERS_1_10)
1832 te->tablespace = ReadStr(AH);
1834 te->owner = ReadStr(AH);
1835 if (AH->version >= K_VERS_1_9)
1837 if (strcmp(ReadStr(AH), "true") == 0)
1838 te->withOids = true;
1840 te->withOids = false;
1843 te->withOids = true;
1845 /* Read TOC entry dependencies */
1846 if (AH->version >= K_VERS_1_5)
1849 deps = (DumpId *) malloc(sizeof(DumpId) * depSize);
1855 break; /* end of list */
1856 if (depIdx >= depSize)
1859 deps = (DumpId *) realloc(deps, sizeof(DumpId) * depSize);
1861 sscanf(tmp, "%d", &deps[depIdx]);
1866 if (depIdx > 0) /* We have a non-null entry */
1868 deps = (DumpId *) realloc(deps, sizeof(DumpId) * depIdx);
1869 te->dependencies = deps;
1875 te->dependencies = NULL;
1881 te->dependencies = NULL;
1885 if (AH->ReadExtraTocPtr)
1886 (*AH->ReadExtraTocPtr) (AH, te);
1888 ahlog(AH, 3, "read TOC entry %d (ID %d) for %s %s\n",
1889 i, te->dumpId, te->desc, te->tag);
1891 te->prev = AH->toc->prev;
1892 AH->toc->prev->next = te;
1899 _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls)
1901 teReqs res = REQ_ALL;
1903 /* ENCODING objects are dumped specially, so always reject here */
1904 if (strcmp(te->desc, "ENCODING") == 0)
1907 /* If it's an ACL, maybe ignore it */
1908 if ((!include_acls || ropt->aclsSkip) && strcmp(te->desc, "ACL") == 0)
1911 if (!ropt->create && strcmp(te->desc, "DATABASE") == 0)
1914 /* Check options for selective dump/restore */
1915 if (ropt->schemaNames)
1917 /* If no namespace is specified, it means all. */
1920 if (strcmp(ropt->schemaNames, te->namespace) != 0)
1926 if (strcmp(te->desc, "TABLE") == 0 ||
1927 strcmp(te->desc, "TABLE DATA") == 0)
1929 if (!ropt->selTable)
1931 if (ropt->tableNames && strcmp(ropt->tableNames, te->tag) != 0)
1934 else if (strcmp(te->desc, "INDEX") == 0)
1936 if (!ropt->selIndex)
1938 if (ropt->indexNames && strcmp(ropt->indexNames, te->tag) != 0)
1941 else if (strcmp(te->desc, "FUNCTION") == 0)
1943 if (!ropt->selFunction)
1945 if (ropt->functionNames && strcmp(ropt->functionNames, te->tag) != 0)
1948 else if (strcmp(te->desc, "TRIGGER") == 0)
1950 if (!ropt->selTrigger)
1952 if (ropt->triggerNames && strcmp(ropt->triggerNames, te->tag) != 0)
1960 * Check if we had a dataDumper. Indicates if the entry is schema or data
1965 * Special Case: If 'SEQUENCE SET' then it is considered a data entry
1967 if (strcmp(te->desc, "SEQUENCE SET") == 0)
1968 res = res & REQ_DATA;
1970 res = res & ~REQ_DATA;
1974 * Special case: <Init> type with <Max OID> tag; this is obsolete and we
1977 if ((strcmp(te->desc, "<Init>") == 0) && (strcmp(te->tag, "Max OID") == 0))
1980 /* Mask it if we only want schema */
1981 if (ropt->schemaOnly)
1982 res = res & REQ_SCHEMA;
1984 /* Mask it we only want data */
1986 res = res & REQ_DATA;
1988 /* Mask it if we don't have a schema contribution */
1989 if (!te->defn || strlen(te->defn) == 0)
1990 res = res & ~REQ_SCHEMA;
1992 /* Finally, if we used a list, limit based on that as well */
1993 if (ropt->limitToList && !ropt->idWanted[te->dumpId - 1])
2000 * Issue SET commands for parameters that we want to have set the same way
2001 * at all times during execution of a restore script.
2004 _doSetFixedOutputState(ArchiveHandle *AH)
2008 /* If we have an encoding setting, emit that */
2010 while (te != AH->toc)
2012 if (strcmp(te->desc, "ENCODING") == 0)
2014 ahprintf(AH, "%s", te->defn);
2020 /* Make sure function checking is disabled */
2021 ahprintf(AH, "SET check_function_bodies = false;\n");
2023 /* Avoid annoying notices etc */
2024 ahprintf(AH, "SET client_min_messages = warning;\n");
2030 * Issue a SET SESSION AUTHORIZATION command. Caller is responsible
2031 * for updating state if appropriate. If user is NULL or an empty string,
2032 * the specification DEFAULT will be used.
2035 _doSetSessionAuth(ArchiveHandle *AH, const char *user)
2037 PQExpBuffer cmd = createPQExpBuffer();
2039 appendPQExpBuffer(cmd, "SET SESSION AUTHORIZATION ");
2042 * SQL requires a string literal here. Might as well be correct.
2045 appendStringLiteral(cmd, user, false);
2047 appendPQExpBuffer(cmd, "DEFAULT");
2048 appendPQExpBuffer(cmd, ";");
2050 if (RestoringToDB(AH))
2054 res = PQexec(AH->connection, cmd->data);
2056 if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
2057 /* NOT warn_or_die_horribly... use -O instead to skip this. */
2058 die_horribly(AH, modulename, "could not set session user to \"%s\": %s",
2059 user, PQerrorMessage(AH->connection));
2064 ahprintf(AH, "%s\n\n", cmd->data);
2066 destroyPQExpBuffer(cmd);
2071 * Issue a SET default_with_oids command. Caller is responsible
2072 * for updating state if appropriate.
2075 _doSetWithOids(ArchiveHandle *AH, const bool withOids)
2077 PQExpBuffer cmd = createPQExpBuffer();
2079 appendPQExpBuffer(cmd, "SET default_with_oids = %s;", withOids ?
2082 if (RestoringToDB(AH))
2086 res = PQexec(AH->connection, cmd->data);
2088 if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
2089 warn_or_die_horribly(AH, modulename,
2090 "could not set default_with_oids: %s",
2091 PQerrorMessage(AH->connection));
2096 ahprintf(AH, "%s\n\n", cmd->data);
2098 destroyPQExpBuffer(cmd);
2103 * Issue the commands to connect to the specified database.
2105 * If we're currently restoring right into a database, this will
2106 * actually establish a connection. Otherwise it puts a \connect into
2107 * the script output.
2109 * NULL dbname implies reconnecting to the current DB (pretty useless).
2112 _reconnectToDB(ArchiveHandle *AH, const char *dbname)
2114 if (RestoringToDB(AH))
2115 ReconnectToServer(AH, dbname, NULL);
2118 PQExpBuffer qry = createPQExpBuffer();
2120 appendPQExpBuffer(qry, "\\connect %s\n\n",
2121 dbname ? fmtId(dbname) : "-");
2122 ahprintf(AH, "%s", qry->data);
2123 destroyPQExpBuffer(qry);
2127 * NOTE: currUser keeps track of what the imaginary session user in our
2128 * script is. It's now effectively reset to the original userID.
2133 AH->currUser = strdup("");
2135 /* don't assume we still know the output schema */
2137 free(AH->currSchema);
2138 AH->currSchema = strdup("");
2139 AH->currWithOids = -1;
2141 /* re-establish fixed state */
2142 _doSetFixedOutputState(AH);
2146 * Become the specified user, and update state to avoid redundant commands
2148 * NULL or empty argument is taken to mean restoring the session default
2151 _becomeUser(ArchiveHandle *AH, const char *user)
2154 user = ""; /* avoid null pointers */
2156 if (AH->currUser && strcmp(AH->currUser, user) == 0)
2157 return; /* no need to do anything */
2159 _doSetSessionAuth(AH, user);
2162 * NOTE: currUser keeps track of what the imaginary session user in our
2168 AH->currUser = strdup(user);
2172 * Become the owner of the the given TOC entry object. If
2173 * changes in ownership are not allowed, this doesn't do anything.
2176 _becomeOwner(ArchiveHandle *AH, TocEntry *te)
2178 if (AH->ropt && (AH->ropt->noOwner || !AH->ropt->use_setsessauth))
2181 _becomeUser(AH, te->owner);
2186 * Set the proper default_with_oids value for the table.
2189 _setWithOids(ArchiveHandle *AH, TocEntry *te)
2191 if (AH->currWithOids != te->withOids)
2193 _doSetWithOids(AH, te->withOids);
2194 AH->currWithOids = te->withOids;
2200 * Issue the commands to select the specified schema as the current schema
2201 * in the target database.
2204 _selectOutputSchema(ArchiveHandle *AH, const char *schemaName)
2208 if (!schemaName || *schemaName == '\0' ||
2209 (AH->currSchema && strcmp(AH->currSchema, schemaName) == 0))
2210 return; /* no need to do anything */
2212 qry = createPQExpBuffer();
2214 appendPQExpBuffer(qry, "SET search_path = %s",
2216 if (strcmp(schemaName, "pg_catalog") != 0)
2217 appendPQExpBuffer(qry, ", pg_catalog");
2219 if (RestoringToDB(AH))
2223 res = PQexec(AH->connection, qry->data);
2225 if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
2226 warn_or_die_horribly(AH, modulename,
2227 "could not set search_path to \"%s\": %s",
2228 schemaName, PQerrorMessage(AH->connection));
2233 ahprintf(AH, "%s;\n\n", qry->data);
2236 free(AH->currSchema);
2237 AH->currSchema = strdup(schemaName);
2239 destroyPQExpBuffer(qry);
2243 * Issue the commands to select the specified tablespace as the current one
2244 * in the target database.
2247 _selectTablespace(ArchiveHandle *AH, const char *tablespace)
2253 have = AH->currTablespace;
2256 /* no need to do anything for non-tablespace object */
2260 if (have && strcmp(want, have) == 0)
2261 return; /* no need to do anything */
2263 qry = createPQExpBuffer();
2265 if (strcmp(want, "") == 0)
2267 /* We want the tablespace to be the database's default */
2268 appendPQExpBuffer(qry, "SET default_tablespace = ''");
2272 /* We want an explicit tablespace */
2273 appendPQExpBuffer(qry, "SET default_tablespace = %s", fmtId(want));
2276 if (RestoringToDB(AH))
2280 res = PQexec(AH->connection, qry->data);
2282 if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
2283 warn_or_die_horribly(AH, modulename,
2284 "could not set default_tablespace to %s: %s",
2285 fmtId(want), PQerrorMessage(AH->connection));
2290 ahprintf(AH, "%s;\n\n", qry->data);
2292 if (AH->currTablespace)
2293 free(AH->currTablespace);
2294 AH->currTablespace = strdup(want);
2296 destroyPQExpBuffer(qry);
2300 * Extract an object description for a TOC entry, and append it to buf.
2302 * This is not quite as general as it may seem, since it really only
2303 * handles constructing the right thing to put into ALTER ... OWNER TO.
2305 * The whole thing is pretty grotty, but we are kind of stuck since the
2306 * information used is all that's available in older dump files.
2309 _getObjectDescription(PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH)
2311 const char *type = te->desc;
2313 /* Use ALTER TABLE for views and sequences */
2314 if (strcmp(type, "VIEW") == 0 || strcmp(type, "SEQUENCE") == 0)
2317 /* objects named by a schema and name */
2318 if (strcmp(type, "CONVERSION") == 0 ||
2319 strcmp(type, "DOMAIN") == 0 ||
2320 strcmp(type, "TABLE") == 0 ||
2321 strcmp(type, "TYPE") == 0)
2323 appendPQExpBuffer(buf, "%s ", type);
2324 if (te->namespace && te->namespace[0]) /* is null pre-7.3 */
2325 appendPQExpBuffer(buf, "%s.", fmtId(te->namespace));
2328 * Pre-7.3 pg_dump would sometimes (not always) put a fmtId'd name
2329 * into te->tag for an index. This check is heuristic, so make its
2330 * scope as narrow as possible.
2332 if (AH->version < K_VERS_1_7 &&
2333 te->tag[0] == '"' &&
2334 te->tag[strlen(te->tag) - 1] == '"' &&
2335 strcmp(type, "INDEX") == 0)
2336 appendPQExpBuffer(buf, "%s", te->tag);
2338 appendPQExpBuffer(buf, "%s", fmtId(te->tag));
2342 /* objects named by just a name */
2343 if (strcmp(type, "DATABASE") == 0 ||
2344 strcmp(type, "SCHEMA") == 0)
2346 appendPQExpBuffer(buf, "%s %s", type, fmtId(te->tag));
2351 * These object types require additional decoration. Fortunately, the
2352 * information needed is exactly what's in the DROP command.
2354 if (strcmp(type, "AGGREGATE") == 0 ||
2355 strcmp(type, "FUNCTION") == 0 ||
2356 strcmp(type, "OPERATOR") == 0 ||
2357 strcmp(type, "OPERATOR CLASS") == 0)
2359 /* Chop "DROP " off the front and make a modifiable copy */
2360 char *first = strdup(te->dropStmt + 5);
2363 /* point to last character in string */
2364 last = first + strlen(first) - 1;
2366 /* Strip off any ';' or '\n' at the end */
2367 while (last >= first && (*last == '\n' || *last == ';'))
2371 appendPQExpBufferStr(buf, first);
2377 write_msg(modulename, "WARNING: don't know how to set owner for object type %s\n",
2382 _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData, bool acl_pass)
2384 /* ACLs are dumped only during acl pass */
2387 if (strcmp(te->desc, "ACL") != 0)
2392 if (strcmp(te->desc, "ACL") == 0)
2397 * Avoid dumping the public schema, as it will already be created ...
2398 * unless we are using --clean mode, in which case it's been deleted and
2399 * we'd better recreate it.
2401 if (!ropt->dropSchema &&
2402 strcmp(te->desc, "SCHEMA") == 0 && strcmp(te->tag, "public") == 0)
2405 /* Select owner, schema, and tablespace as necessary */
2406 _becomeOwner(AH, te);
2407 _selectOutputSchema(AH, te->namespace);
2408 _selectTablespace(AH, te->tablespace);
2410 /* Set up OID mode too */
2411 if (strcmp(te->desc, "TABLE") == 0)
2412 _setWithOids(AH, te);
2414 /* Emit header comment for item */
2415 if (!AH->noTocComments)
2424 ahprintf(AH, "--\n");
2425 if (AH->public.verbose)
2427 ahprintf(AH, "-- TOC entry %d (class %u OID %u)\n",
2428 te->dumpId, te->catalogId.tableoid, te->catalogId.oid);
2433 ahprintf(AH, "-- Dependencies:");
2434 for (i = 0; i < te->nDeps; i++)
2435 ahprintf(AH, " %d", te->dependencies[i]);
2439 ahprintf(AH, "-- %sName: %s; Type: %s; Schema: %s; Owner: %s",
2440 pfx, te->tag, te->desc,
2441 te->namespace ? te->namespace : "-",
2442 ropt->noOwner ? "-" : te->owner);
2444 ahprintf(AH, "; Tablespace: %s", te->tablespace);
2447 if (AH->PrintExtraTocPtr !=NULL)
2448 (*AH->PrintExtraTocPtr) (AH, te);
2449 ahprintf(AH, "--\n\n");
2453 * Actually print the definition.
2455 * Really crude hack for suppressing AUTHORIZATION clause that old pg_dump
2456 * versions put into CREATE SCHEMA. We have to do this when --no-owner
2457 * mode is selected. This is ugly, but I see no other good way ...
2459 if (ropt->noOwner && strcmp(te->desc, "SCHEMA") == 0)
2461 ahprintf(AH, "CREATE SCHEMA %s;\n\n\n", fmtId(te->tag));
2465 if (strlen(te->defn) > 0)
2466 ahprintf(AH, "%s\n\n", te->defn);
2470 * If we aren't using SET SESSION AUTH to determine ownership, we must
2471 * instead issue an ALTER OWNER command. We assume that anything without
2472 * a DROP command is not a separately ownable object. All the categories
2473 * with DROP commands must appear in one list or the other.
2475 if (!ropt->noOwner && !ropt->use_setsessauth &&
2476 strlen(te->owner) > 0 && strlen(te->dropStmt) > 0)
2478 if (strcmp(te->desc, "AGGREGATE") == 0 ||
2479 strcmp(te->desc, "CONVERSION") == 0 ||
2480 strcmp(te->desc, "DATABASE") == 0 ||
2481 strcmp(te->desc, "DOMAIN") == 0 ||
2482 strcmp(te->desc, "FUNCTION") == 0 ||
2483 strcmp(te->desc, "OPERATOR") == 0 ||
2484 strcmp(te->desc, "OPERATOR CLASS") == 0 ||
2485 strcmp(te->desc, "SCHEMA") == 0 ||
2486 strcmp(te->desc, "TABLE") == 0 ||
2487 strcmp(te->desc, "TYPE") == 0 ||
2488 strcmp(te->desc, "VIEW") == 0 ||
2489 strcmp(te->desc, "SEQUENCE") == 0)
2491 PQExpBuffer temp = createPQExpBuffer();
2493 appendPQExpBuffer(temp, "ALTER ");
2494 _getObjectDescription(temp, te, AH);
2495 appendPQExpBuffer(temp, " OWNER TO %s;", fmtId(te->owner));
2496 ahprintf(AH, "%s\n\n", temp->data);
2497 destroyPQExpBuffer(temp);
2499 else if (strcmp(te->desc, "CAST") == 0 ||
2500 strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
2501 strcmp(te->desc, "CONSTRAINT") == 0 ||
2502 strcmp(te->desc, "DEFAULT") == 0 ||
2503 strcmp(te->desc, "FK CONSTRAINT") == 0 ||
2504 strcmp(te->desc, "INDEX") == 0 ||
2505 strcmp(te->desc, "PROCEDURAL LANGUAGE") == 0 ||
2506 strcmp(te->desc, "RULE") == 0 ||
2507 strcmp(te->desc, "TRIGGER") == 0)
2509 /* these object types don't have separate owners */
2513 write_msg(modulename, "WARNING: don't know how to set owner for object type %s\n",
2519 * If it's an ACL entry, it might contain SET SESSION AUTHORIZATION
2520 * commands, so we can no longer assume we know the current auth setting.
2522 if (strncmp(te->desc, "ACL", 3) == 0)
2526 AH->currUser = NULL;
2531 WriteHead(ArchiveHandle *AH)
2535 (*AH->WriteBufPtr) (AH, "PGDMP", 5); /* Magic code */
2536 (*AH->WriteBytePtr) (AH, AH->vmaj);
2537 (*AH->WriteBytePtr) (AH, AH->vmin);
2538 (*AH->WriteBytePtr) (AH, AH->vrev);
2539 (*AH->WriteBytePtr) (AH, AH->intSize);
2540 (*AH->WriteBytePtr) (AH, AH->offSize);
2541 (*AH->WriteBytePtr) (AH, AH->format);
2544 if (AH->compression != 0)
2545 write_msg(modulename, "WARNING: requested compression not available in this "
2546 "installation -- archive will be uncompressed\n");
2548 AH->compression = 0;
2551 WriteInt(AH, AH->compression);
2553 crtm = *localtime(&AH->createDate);
2554 WriteInt(AH, crtm.tm_sec);
2555 WriteInt(AH, crtm.tm_min);
2556 WriteInt(AH, crtm.tm_hour);
2557 WriteInt(AH, crtm.tm_mday);
2558 WriteInt(AH, crtm.tm_mon);
2559 WriteInt(AH, crtm.tm_year);
2560 WriteInt(AH, crtm.tm_isdst);
2561 WriteStr(AH, PQdb(AH->connection));
2562 WriteStr(AH, AH->public.remoteVersionStr);
2563 WriteStr(AH, PG_VERSION);
2567 ReadHead(ArchiveHandle *AH)
2573 /* If we haven't already read the header... */
2574 if (!AH->readHeader)
2577 (*AH->ReadBufPtr) (AH, tmpMag, 5);
2579 if (strncmp(tmpMag, "PGDMP", 5) != 0)
2580 die_horribly(AH, modulename, "did not find magic string in file header\n");
2582 AH->vmaj = (*AH->ReadBytePtr) (AH);
2583 AH->vmin = (*AH->ReadBytePtr) (AH);
2585 if (AH->vmaj > 1 || ((AH->vmaj == 1) && (AH->vmin > 0))) /* Version > 1.0 */
2586 AH->vrev = (*AH->ReadBytePtr) (AH);
2590 AH->version = ((AH->vmaj * 256 + AH->vmin) * 256 + AH->vrev) * 256 + 0;
2593 if (AH->version < K_VERS_1_0 || AH->version > K_VERS_MAX)
2594 die_horribly(AH, modulename, "unsupported version (%d.%d) in file header\n",
2595 AH->vmaj, AH->vmin);
2597 AH->intSize = (*AH->ReadBytePtr) (AH);
2598 if (AH->intSize > 32)
2599 die_horribly(AH, modulename, "sanity check on integer size (%lu) failed\n",
2600 (unsigned long) AH->intSize);
2602 if (AH->intSize > sizeof(int))
2603 write_msg(modulename, "WARNING: archive was made on a machine with larger integers, some operations may fail\n");
2605 if (AH->version >= K_VERS_1_7)
2606 AH->offSize = (*AH->ReadBytePtr) (AH);
2608 AH->offSize = AH->intSize;
2610 fmt = (*AH->ReadBytePtr) (AH);
2612 if (AH->format != fmt)
2613 die_horribly(AH, modulename, "expected format (%d) differs from format found in file (%d)\n",
2617 if (AH->version >= K_VERS_1_2)
2619 if (AH->version < K_VERS_1_4)
2620 AH->compression = (*AH->ReadBytePtr) (AH);
2622 AH->compression = ReadInt(AH);
2625 AH->compression = Z_DEFAULT_COMPRESSION;
2628 if (AH->compression != 0)
2629 write_msg(modulename, "WARNING: archive is compressed, but this installation does not support compression -- no data will be available\n");
2632 if (AH->version >= K_VERS_1_4)
2634 crtm.tm_sec = ReadInt(AH);
2635 crtm.tm_min = ReadInt(AH);
2636 crtm.tm_hour = ReadInt(AH);
2637 crtm.tm_mday = ReadInt(AH);
2638 crtm.tm_mon = ReadInt(AH);
2639 crtm.tm_year = ReadInt(AH);
2640 crtm.tm_isdst = ReadInt(AH);
2642 AH->archdbname = ReadStr(AH);
2644 AH->createDate = mktime(&crtm);
2646 if (AH->createDate == (time_t) -1)
2647 write_msg(modulename, "WARNING: invalid creation date in header\n");
2650 if (AH->version >= K_VERS_1_10)
2652 AH->archiveRemoteVersion = ReadStr(AH);
2653 AH->archiveDumpVersion = ReadStr(AH);
2661 * check to see if fseek can be performed.
2668 if (fseeko(fp, 0, SEEK_CUR) != 0)
2670 else if (sizeof(off_t) > sizeof(long))
2673 * At this point, off_t is too large for long, so we return based on
2674 * whether an off_t version of fseek is available.
2690 dumpTimestamp(ArchiveHandle *AH, const char *msg, time_t tim)
2694 if (strftime(buf, 256, "%Y-%m-%d %H:%M:%S %Z", localtime(&tim)) != 0)
2695 ahprintf(AH, "-- %s %s\n\n", msg, buf);