aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/ref/pg_dump.sgml33
-rw-r--r--doc/src/sgml/ref/pg_restore.sgml35
-rw-r--r--src/bin/pg_dump/dumputils.c61
-rw-r--r--src/bin/pg_dump/dumputils.h14
-rw-r--r--src/bin/pg_dump/pg_backup.h15
-rw-r--r--src/bin/pg_dump/pg_backup_archiver.c162
-rw-r--r--src/bin/pg_dump/pg_backup_archiver.h14
-rw-r--r--src/bin/pg_dump/pg_backup_tar.c10
-rw-r--r--src/bin/pg_dump/pg_dump.c93
-rw-r--r--src/bin/pg_dump/pg_restore.c39
10 files changed, 238 insertions, 238 deletions
diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml
index 12ddd259662..450383083d7 100644
--- a/doc/src/sgml/ref/pg_dump.sgml
+++ b/doc/src/sgml/ref/pg_dump.sgml
@@ -113,10 +113,12 @@ PostgreSQL documentation
<listitem>
<para>
Dump only the data, not the schema (data definitions).
+ Table data, large objects, and sequence values are dumped.
</para>
<para>
- This option is equivalent to specifying <option>--section=data</>.
+ This option is similar to, but for historical reasons not identical
+ to, specifying <option>--section=data</>.
</para>
</listitem>
</varlistentry>
@@ -403,12 +405,18 @@ PostgreSQL documentation
Dump only the object definitions (schema), not data.
</para>
<para>
- To exclude table data for only a subset of tables in the database,
- see <option>--exclude-table-data</>.
+ This option is the inverse of <option>--data-only</>.
+ It is similar to, but for historical reasons not identical to,
+ specifying
+ <option>--section=pre-data --section=post-data</>.
</para>
<para>
- This option is equivalent to specifying
- <option>--section=pre-data --section=post-data</>.
+ (Do not confuse this with the <option>--schema</> option, which
+ uses the word <quote>schema</> in a different meaning.)
+ </para>
+ <para>
+ To exclude table data for only a subset of tables in the database,
+ see <option>--exclude-table-data</>.
</para>
</listitem>
</varlistentry>
@@ -722,14 +730,17 @@ PostgreSQL documentation
<term><option>--section=<replaceable class="parameter">sectionname</replaceable></option></term>
<listitem>
<para>
- Only dump the named section. The name can be one of <option>pre-data</>, <option>data</>
- and <option>post-data</>.
- This option can be specified more than once. The default is to dump all sections.
+ Only dump the named section. The section name can be
+ <option>pre-data</>, <option>data</>, or <option>post-data</>.
+ This option can be specified more than once to select multiple
+ sections. The default is to dump all sections.
</para>
<para>
- Post-data items consist of definitions of indexes, triggers, rules
- and constraints other than validated check constraints.
- Pre-data items consist of all other data definition items.
+ The data section contains actual table data as well as large-object
+ definitions.
+ Post-data items consist of definitions of indexes, triggers, rules
+ and constraints other than validated check constraints.
+ Pre-data items consist of all other data definition items.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/pg_restore.sgml b/doc/src/sgml/ref/pg_restore.sgml
index 513b946e571..bc3d2b7e90f 100644
--- a/doc/src/sgml/ref/pg_restore.sgml
+++ b/doc/src/sgml/ref/pg_restore.sgml
@@ -92,9 +92,13 @@
<listitem>
<para>
Restore only the data, not the schema (data definitions).
+ Table data, large objects, and sequence values are restored,
+ if present in the archive.
</para>
+
<para>
- This option is equivalent to specifying <option>--section=data</>.
+ This option is similar to, but for historical reasons not identical
+ to, specifying <option>--section=data</>.
</para>
</listitem>
</varlistentry>
@@ -357,15 +361,19 @@
<term><option>--schema-only</option></term>
<listitem>
<para>
- Restore only the schema (data definitions), not the data (table
- contents). Current sequence values will not be restored, either.
- (Do not confuse this with the <option>--schema</> option, which
- uses the word <quote>schema</> in a different meaning.)
+ Restore only the schema (data definitions), not data,
+ to the extent that schema entries are present in the archive.
</para>
<para>
- This option is equivalent to specifying
+ This option is the inverse of <option>--data-only</>.
+ It is similar to, but for historical reasons not identical to,
+ specifying
<option>--section=pre-data --section=post-data</>.
</para>
+ <para>
+ (Do not confuse this with the <option>--schema</> option, which
+ uses the word <quote>schema</> in a different meaning.)
+ </para>
</listitem>
</varlistentry>
@@ -515,14 +523,17 @@
<term><option>--section=<replaceable class="parameter">sectionname</replaceable></option></term>
<listitem>
<para>
- Only restore the named section. The name can be one of <option>pre-data</>, <option>data</>
- and <option>post-data</>.
- This option can be specified more than once. The default is to restore all sections.
+ Only restore the named section. The section name can be
+ <option>pre-data</>, <option>data</>, or <option>post-data</>.
+ This option can be specified more than once to select multiple
+ sections. The default is to restore all sections.
</para>
<para>
- Post-data items consist of definitions of indexes, triggers, rules
- and constraints other than validated check constraints.
- Pre-data items consist of all other data definition items.
+ The data section contains actual table data as well as large-object
+ definitions.
+ Post-data items consist of definitions of indexes, triggers, rules
+ and constraints other than validated check constraints.
+ Pre-data items consist of all other data definition items.
</para>
</listitem>
</varlistentry>
diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c
index b662ad107e5..623c250eb89 100644
--- a/src/bin/pg_dump/dumputils.c
+++ b/src/bin/pg_dump/dumputils.c
@@ -17,7 +17,6 @@
#include <ctype.h>
#include "dumputils.h"
-#include "pg_backup.h"
#include "parser/keywords.h"
@@ -1231,6 +1230,37 @@ emitShSecLabels(PGconn *conn, PGresult *res, PQExpBuffer buffer,
/*
+ * Parse a --section=foo command line argument.
+ *
+ * Set or update the bitmask in *dumpSections according to arg.
+ * dumpSections is initialised as DUMP_UNSECTIONED by pg_dump and
+ * pg_restore so they can know if this has even been called.
+ */
+void
+set_dump_section(const char *arg, int *dumpSections)
+{
+ /* if this is the first call, clear all the bits */
+ if (*dumpSections == DUMP_UNSECTIONED)
+ *dumpSections = 0;
+
+ if (strcmp(arg,"pre-data") == 0)
+ *dumpSections |= DUMP_PRE_DATA;
+ else if (strcmp(arg,"data") == 0)
+ *dumpSections |= DUMP_DATA;
+ else if (strcmp(arg,"post-data") == 0)
+ *dumpSections |= DUMP_POST_DATA;
+ else
+ {
+ fprintf(stderr, _("%s: unknown section name \"%s\")\n"),
+ progname, arg);
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
+ progname);
+ exit_nicely(1);
+ }
+}
+
+
+/*
* Write a printf-style message to stderr.
*
* The program name is prepended, if "progname" has been set.
@@ -1279,35 +1309,6 @@ exit_horribly(const char *modulename, const char *fmt,...)
exit_nicely(1);
}
-/*
- * Set the bitmask in dumpSections according to the first argument.
- * dumpSections is initialised as DUMP_UNSECTIONED by pg_dump and
- * pg_restore so they can know if this has even been called.
- */
-
-void
-set_section (const char *arg, int *dumpSections)
-{
- /* if this is the first, clear all the bits */
- if (*dumpSections == DUMP_UNSECTIONED)
- *dumpSections = 0;
-
- if (strcmp(arg,"pre-data") == 0)
- *dumpSections |= DUMP_PRE_DATA;
- else if (strcmp(arg,"data") == 0)
- *dumpSections |= DUMP_DATA;
- else if (strcmp(arg,"post-data") == 0)
- *dumpSections |= DUMP_POST_DATA;
- else
- {
- fprintf(stderr, _("%s: unknown section name \"%s\")\n"),
- progname, arg);
- fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
- progname);
- exit_nicely(1);
- }
-}
-
/* Register a callback to be run when exit_nicely is invoked. */
void
on_exit_nicely(on_exit_nicely_callback function, void *arg)
diff --git a/src/bin/pg_dump/dumputils.h b/src/bin/pg_dump/dumputils.h
index 82cf940892c..3d1ed9570ab 100644
--- a/src/bin/pg_dump/dumputils.h
+++ b/src/bin/pg_dump/dumputils.h
@@ -19,6 +19,16 @@
#include "libpq-fe.h"
#include "pqexpbuffer.h"
+typedef enum /* bits returned by set_dump_section */
+{
+ DUMP_PRE_DATA = 0x01,
+ DUMP_DATA = 0x02,
+ DUMP_POST_DATA = 0x04,
+ DUMP_UNSECTIONED = 0xff
+} DumpSections;
+
+typedef void (*on_exit_nicely_callback) (int code, void *arg);
+
extern int quote_all_identifiers;
extern const char *progname;
@@ -52,15 +62,13 @@ extern void buildShSecLabelQuery(PGconn *conn, const char *catalog_name,
uint32 objectId, PQExpBuffer sql);
extern void emitShSecLabels(PGconn *conn, PGresult *res,
PQExpBuffer buffer, const char *target, const char *objname);
+extern void set_dump_section(const char *arg, int *dumpSections);
extern void write_msg(const char *modulename, const char *fmt,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
extern void vwrite_msg(const char *modulename, const char *fmt, va_list ap)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)));
extern void exit_horribly(const char *modulename, const char *fmt,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3), noreturn));
-extern void set_section (const char *arg, int *dumpSections);
-
-typedef void (*on_exit_nicely_callback) (int code, void *arg);
extern void on_exit_nicely(on_exit_nicely_callback function, void *arg);
extern void exit_nicely(int code) __attribute__((noreturn));
diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h
index 61c68636669..bf7cc1c1ac8 100644
--- a/src/bin/pg_dump/pg_backup.h
+++ b/src/bin/pg_dump/pg_backup.h
@@ -68,14 +68,6 @@ typedef enum _teSection
SECTION_POST_DATA /* stuff to be processed after data */
} teSection;
-typedef enum
-{
- DUMP_PRE_DATA = 0x01,
- DUMP_DATA = 0x02,
- DUMP_POST_DATA = 0x04,
- DUMP_UNSECTIONED = 0xff
-} DumpSections;
-
/*
* We may want to have some more user-readable data, but in the mean
* time this gives us some abstraction and type checking.
@@ -114,9 +106,9 @@ typedef struct _restoreOptions
int no_security_labels; /* Skip security label entries */
char *superuser; /* Username to use as superuser */
char *use_role; /* Issue SET ROLE to this */
- int dataOnly;
int dropSchema;
const char *filename;
+ int dataOnly;
int schemaOnly;
int dumpSections;
int verbose;
@@ -187,7 +179,9 @@ extern int EndBlob(Archive *AH, Oid oid);
extern void CloseArchive(Archive *AH);
-extern void RestoreArchive(Archive *AH, RestoreOptions *ropt);
+extern void SetArchiveRestoreOptions(Archive *AH, RestoreOptions *ropt);
+
+extern void RestoreArchive(Archive *AH);
/* Open an existing archive */
extern Archive *OpenArchive(const char *FileSpec, const ArchiveFormat fmt);
@@ -203,7 +197,6 @@ extern RestoreOptions *NewRestoreOptions(void);
/* Rearrange and filter TOC entries */
extern void SortTocFromFile(Archive *AHX, RestoreOptions *ropt);
-extern void InitDummyWantedList(Archive *AHX, RestoreOptions *ropt);
/* Convenience functions used only when writing DATA */
extern int archputs(const char *s, Archive *AH);
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index 7aaba36385c..c049becf126 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -131,7 +131,7 @@ static void _selectOutputSchema(ArchiveHandle *AH, const char *schemaName);
static void _selectTablespace(ArchiveHandle *AH, const char *tablespace);
static void processEncodingEntry(ArchiveHandle *AH, TocEntry *te);
static void processStdStringsEntry(ArchiveHandle *AH, TocEntry *te);
-static teReqs _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls);
+static teReqs _tocEntryRequired(TocEntry *te, teSection curSection, RestoreOptions *ropt);
static bool _tocEntryIsACL(TocEntry *te);
static void _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
static void _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
@@ -234,15 +234,35 @@ CloseArchive(Archive *AHX)
/* Public */
void
-RestoreArchive(Archive *AHX, RestoreOptions *ropt)
+SetArchiveRestoreOptions(Archive *AHX, RestoreOptions *ropt)
{
ArchiveHandle *AH = (ArchiveHandle *) AHX;
+ TocEntry *te;
+ teSection curSection;
+
+ /* Save options for later access */
+ AH->ropt = ropt;
+
+ /* Decide which TOC entries will be dumped/restored, and mark them */
+ curSection = SECTION_PRE_DATA;
+ for (te = AH->toc->next; te != AH->toc; te = te->next)
+ {
+ if (te->section != SECTION_NONE)
+ curSection = te->section;
+ te->reqs = _tocEntryRequired(te, curSection, ropt);
+ }
+}
+
+/* Public */
+void
+RestoreArchive(Archive *AHX)
+{
+ ArchiveHandle *AH = (ArchiveHandle *) AHX;
+ RestoreOptions *ropt = AH->ropt;
bool parallel_mode;
TocEntry *te;
- teReqs reqs;
OutputContext sav;
- AH->ropt = ropt;
AH->stage = STAGE_INITIALIZING;
/*
@@ -292,8 +312,7 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
{
for (te = AH->toc->next; te != AH->toc; te = te->next)
{
- reqs = _tocEntryRequired(te, ropt, false);
- if (te->hadDumper && (reqs & REQ_DATA) != 0)
+ if (te->hadDumper && (te->reqs & REQ_DATA) != 0)
exit_horribly(modulename, "cannot restore from compressed archive (compression not supported in this installation)\n");
}
}
@@ -345,8 +364,7 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
for (te = AH->toc->next; te != AH->toc; te = te->next)
{
- reqs = _tocEntryRequired(te, ropt, true);
- if ((reqs & REQ_SCHEMA) != 0)
+ if ((te->reqs & REQ_SCHEMA) != 0)
{ /* It's schema, and it's wanted */
impliedDataOnly = 0;
break;
@@ -403,9 +421,8 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
{
AH->currentTE = te;
- reqs = _tocEntryRequired(te, ropt, false /* needn't drop ACLs */ );
/* We want anything that's selected and has a dropStmt */
- if (((reqs & (REQ_SCHEMA | REQ_DATA)) != 0) && te->dropStmt)
+ if (((te->reqs & (REQ_SCHEMA | REQ_DATA)) != 0) && te->dropStmt)
{
ahlog(AH, 1, "dropping %s %s\n", te->desc, te->tag);
/* Select owner and schema as necessary */
@@ -453,11 +470,8 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
{
AH->currentTE = te;
- /* Work out what, if anything, we want from this entry */
- reqs = _tocEntryRequired(te, ropt, true);
-
/* Both schema and data objects might now have ownership/ACLs */
- if ((reqs & (REQ_SCHEMA | REQ_DATA)) != 0)
+ if ((te->reqs & (REQ_SCHEMA | REQ_DATA)) != 0)
{
ahlog(AH, 1, "setting owner and privileges for %s %s\n",
te->desc, te->tag);
@@ -508,7 +522,18 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te,
AH->currentTE = te;
/* Work out what, if anything, we want from this entry */
- reqs = _tocEntryRequired(te, ropt, false);
+ if (_tocEntryIsACL(te))
+ reqs = 0; /* ACLs are never restored here */
+ else
+ reqs = te->reqs;
+
+ /*
+ * Ignore DATABASE entry unless we should create it. We must check this
+ * here, not in _tocEntryRequired, because the createDB option should
+ * not affect emitting a DATABASE entry to an archive file.
+ */
+ if (!ropt->createDB && strcmp(te->desc, "DATABASE") == 0)
+ reqs = 0;
/* Dump any relevant dump warnings to stderr */
if (!ropt->suppressDumpWarnings && strcmp(te->desc, "WARNING") == 0)
@@ -588,7 +613,7 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te,
/*
* If we can output the data, then restore it.
*/
- if (AH->PrintTocDataPtr !=NULL && (reqs & REQ_DATA) != 0)
+ if (AH->PrintTocDataPtr !=NULL)
{
_printTocEntry(AH, te, ropt, true, false);
@@ -841,8 +866,9 @@ PrintTOCSummary(Archive *AHX, RestoreOptions *ropt)
{
ArchiveHandle *AH = (ArchiveHandle *) AHX;
TocEntry *te;
+ teSection curSection;
OutputContext sav;
- char *fmtName;
+ const char *fmtName;
sav = SaveOutput(AH);
if (ropt->filename)
@@ -880,9 +906,13 @@ PrintTOCSummary(Archive *AHX, RestoreOptions *ropt)
/* We should print DATABASE entries whether or not -C was specified */
ropt->createDB = 1;
+ curSection = SECTION_PRE_DATA;
for (te = AH->toc->next; te != AH->toc; te = te->next)
{
- if (ropt->verbose || _tocEntryRequired(te, ropt, true) != 0)
+ if (te->section != SECTION_NONE)
+ curSection = te->section;
+ if (ropt->verbose ||
+ (_tocEntryRequired(te, curSection, ropt) & (REQ_SCHEMA | REQ_DATA)) != 0)
ahprintf(AH, "%d; %u %u %s %s %s %s\n", te->dumpId,
te->catalogId.tableoid, te->catalogId.oid,
te->desc, te->namespace ? te->namespace : "-",
@@ -1135,19 +1165,6 @@ SortTocFromFile(Archive *AHX, RestoreOptions *ropt)
strerror(errno));
}
-/*
- * Set up a dummy ID filter that selects all dump IDs
- */
-void
-InitDummyWantedList(Archive *AHX, RestoreOptions *ropt)
-{
- ArchiveHandle *AH = (ArchiveHandle *) AHX;
-
- /* Allocate space for the 'wanted' array, and init it to 1's */
- ropt->idWanted = (bool *) pg_malloc(sizeof(bool) * AH->maxDumpId);
- memset(ropt->idWanted, 1, sizeof(bool) * AH->maxDumpId);
-}
-
/**********************
* 'Convenience functions that look like standard IO functions
* for writing data when in dump mode.
@@ -1591,14 +1608,14 @@ getTocEntryByDumpId(ArchiveHandle *AH, DumpId id)
}
teReqs
-TocIDRequired(ArchiveHandle *AH, DumpId id, RestoreOptions *ropt)
+TocIDRequired(ArchiveHandle *AH, DumpId id)
{
TocEntry *te = getTocEntryByDumpId(AH, id);
if (!te)
return 0;
- return _tocEntryRequired(te, ropt, true);
+ return te->reqs;
}
size_t
@@ -2082,7 +2099,7 @@ WriteDataChunks(ArchiveHandle *AH)
for (te = AH->toc->next; te != AH->toc; te = te->next)
{
- if (te->dataDumper != NULL)
+ if (te->dataDumper != NULL && (te->reqs & REQ_DATA) != 0)
{
AH->currToc = te;
/* printf("Writing data for %d (%x)\n", te->id, te); */
@@ -2123,14 +2140,26 @@ WriteToc(ArchiveHandle *AH)
{
TocEntry *te;
char workbuf[32];
+ int tocCount;
int i;
- /* printf("%d TOC Entries to save\n", AH->tocCount); */
+ /* count entries that will actually be dumped */
+ tocCount = 0;
+ for (te = AH->toc->next; te != AH->toc; te = te->next)
+ {
+ if ((te->reqs & (REQ_SCHEMA | REQ_DATA | REQ_SPECIAL)) != 0)
+ tocCount++;
+ }
+
+ /* printf("%d TOC Entries to save\n", tocCount); */
- WriteInt(AH, AH->tocCount);
+ WriteInt(AH, tocCount);
for (te = AH->toc->next; te != AH->toc; te = te->next)
{
+ if ((te->reqs & (REQ_SCHEMA | REQ_DATA | REQ_SPECIAL)) == 0)
+ continue;
+
WriteInt(AH, te->dumpId);
WriteInt(AH, te->dataDumper ? 1 : 0);
@@ -2173,7 +2202,6 @@ ReadToc(ArchiveHandle *AH)
int depIdx;
int depSize;
TocEntry *te;
- bool in_post_data = false;
AH->tocCount = ReadInt(AH);
AH->maxDumpId = 0;
@@ -2239,12 +2267,6 @@ ReadToc(ArchiveHandle *AH)
te->section = SECTION_PRE_DATA;
}
- /* will stay true even for SECTION_NONE items */
- if (te->section == SECTION_POST_DATA)
- in_post_data = true;
-
- te->inPostData = in_post_data;
-
te->defn = ReadStr(AH);
te->dropStmt = ReadStr(AH);
@@ -2373,38 +2395,43 @@ processStdStringsEntry(ArchiveHandle *AH, TocEntry *te)
}
static teReqs
-_tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls)
+_tocEntryRequired(TocEntry *te, teSection curSection, RestoreOptions *ropt)
{
- teReqs res = REQ_ALL;
+ teReqs res = REQ_SCHEMA | REQ_DATA;
- /* ENCODING and STDSTRINGS items are dumped specially, so always reject */
+ /* ENCODING and STDSTRINGS items are treated specially */
if (strcmp(te->desc, "ENCODING") == 0 ||
strcmp(te->desc, "STDSTRINGS") == 0)
- return 0;
+ return REQ_SPECIAL;
/* If it's an ACL, maybe ignore it */
- if ((!include_acls || ropt->aclsSkip) && _tocEntryIsACL(te))
+ if (ropt->aclsSkip && _tocEntryIsACL(te))
return 0;
/* If it's security labels, maybe ignore it */
if (ropt->no_security_labels && strcmp(te->desc, "SECURITY LABEL") == 0)
return 0;
- /* Ignore DATABASE entry unless we should create it */
- if (!ropt->createDB && strcmp(te->desc, "DATABASE") == 0)
- return 0;
-
- /* skip (all but) post data section as required */
- /* table data is filtered if necessary lower down */
- if (ropt->dumpSections != DUMP_UNSECTIONED)
+ /* Ignore it if section is not to be dumped/restored */
+ switch (curSection)
{
- if (!(ropt->dumpSections & DUMP_POST_DATA) && te->inPostData)
- return 0;
- if (!(ropt->dumpSections & DUMP_PRE_DATA) && ! te->inPostData && strcmp(te->desc, "TABLE DATA") != 0)
+ case SECTION_PRE_DATA:
+ if (!(ropt->dumpSections & DUMP_PRE_DATA))
+ return 0;
+ break;
+ case SECTION_DATA:
+ if (!(ropt->dumpSections & DUMP_DATA))
+ return 0;
+ break;
+ case SECTION_POST_DATA:
+ if (!(ropt->dumpSections & DUMP_POST_DATA))
+ return 0;
+ break;
+ default:
+ /* shouldn't get here, really, but ignore it */
return 0;
}
-
/* Check options for selective dump/restore */
if (ropt->schemaNames)
{
@@ -2486,7 +2513,7 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls)
if (ropt->schemaOnly)
res = res & REQ_SCHEMA;
- /* Mask it we only want data */
+ /* Mask it if we only want data */
if (ropt->dataOnly)
res = res & REQ_DATA;
@@ -3553,11 +3580,9 @@ restore_toc_entries_parallel(ArchiveHandle *AH)
{
if (next_work_item != NULL)
{
- teReqs reqs;
-
- /* If not to be dumped, don't waste time launching a worker */
- reqs = _tocEntryRequired(next_work_item, AH->ropt, false);
- if ((reqs & (REQ_SCHEMA | REQ_DATA)) == 0)
+ /* If not to be restored, don't waste time launching a worker */
+ if ((next_work_item->reqs & (REQ_SCHEMA | REQ_DATA)) == 0 ||
+ _tocEntryIsACL(next_work_item))
{
ahlog(AH, 1, "skipping item %d %s %s\n",
next_work_item->dumpId,
@@ -4287,15 +4312,14 @@ mark_create_done(ArchiveHandle *AH, TocEntry *te)
static void
inhibit_data_for_failed_table(ArchiveHandle *AH, TocEntry *te)
{
- RestoreOptions *ropt = AH->ropt;
-
ahlog(AH, 1, "table \"%s\" could not be created, will not restore its data\n",
te->tag);
if (AH->tableDataId[te->dumpId] != 0)
{
- /* mark it unwanted; we assume idWanted array already exists */
- ropt->idWanted[AH->tableDataId[te->dumpId] - 1] = false;
+ TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
+
+ ted->reqs = 0;
}
}
diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h
index 8c764a2d493..4361805baab 100644
--- a/src/bin/pg_dump/pg_backup_archiver.h
+++ b/src/bin/pg_dump/pg_backup_archiver.h
@@ -162,9 +162,9 @@ typedef enum
typedef enum
{
- REQ_SCHEMA = 1,
- REQ_DATA = 2,
- REQ_ALL = REQ_SCHEMA + REQ_DATA
+ REQ_SCHEMA = 0x01, /* want schema */
+ REQ_DATA = 0x02, /* want data */
+ REQ_SPECIAL = 0x04 /* for special TOC entries */
} teReqs;
typedef struct _archiveHandle
@@ -313,13 +313,13 @@ typedef struct _tocEntry
void *dataDumperArg; /* Arg for above routine */
void *formatData; /* TOC Entry data specific to file format */
- /* in post data? not quite the same as section, might be SECTION_NONE */
- bool inPostData;
+ /* working state while dumping/restoring */
+ teReqs reqs; /* do we need schema and/or data of object */
+ bool created; /* set for DATA member if TABLE was created */
/* working state (needed only for parallel restore) */
struct _tocEntry *par_prev; /* list links for pending/ready items; */
struct _tocEntry *par_next; /* these are NULL if not in either list */
- bool created; /* set for DATA member if TABLE was created */
int depCount; /* number of dependencies not yet restored */
DumpId *revDeps; /* dumpIds of objects depending on this one */
int nRevDeps; /* number of such dependencies */
@@ -339,7 +339,7 @@ extern void WriteToc(ArchiveHandle *AH);
extern void ReadToc(ArchiveHandle *AH);
extern void WriteDataChunks(ArchiveHandle *AH);
-extern teReqs TocIDRequired(ArchiveHandle *AH, DumpId id, RestoreOptions *ropt);
+extern teReqs TocIDRequired(ArchiveHandle *AH, DumpId id);
extern bool checkSeek(FILE *fp);
#define appendStringLiteralAHX(buf,str,AH) \
diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c
index 451c9574f7c..9fe2b14df55 100644
--- a/src/bin/pg_dump/pg_backup_tar.c
+++ b/src/bin/pg_dump/pg_backup_tar.c
@@ -817,6 +817,7 @@ _CloseArchive(ArchiveHandle *AH)
lclContext *ctx = (lclContext *) AH->formatData;
TAR_MEMBER *th;
RestoreOptions *ropt;
+ RestoreOptions *savRopt;
int savVerbose,
i;
@@ -860,16 +861,21 @@ _CloseArchive(ArchiveHandle *AH)
ctx->scriptTH = th;
ropt = NewRestoreOptions();
+ memcpy(ropt, AH->ropt, sizeof(RestoreOptions));
ropt->dropSchema = 1;
ropt->compression = 0;
ropt->superuser = NULL;
ropt->suppressDumpWarnings = true;
+ savRopt = AH->ropt;
+ AH->ropt = ropt;
+
savVerbose = AH->public.verbose;
AH->public.verbose = 0;
- RestoreArchive((Archive *) AH, ropt);
+ RestoreArchive((Archive *) AH);
+ AH->ropt = savRopt;
AH->public.verbose = savVerbose;
tarClose(AH, th);
@@ -1176,7 +1182,7 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename)
ahlog(AH, 4, "skipping tar member %s\n", th->targetFile);
id = atoi(th->targetFile);
- if ((TocIDRequired(AH, id, AH->ropt) & REQ_DATA) != 0)
+ if ((TocIDRequired(AH, id) & REQ_DATA) != 0)
exit_horribly(modulename, "restoring data out of order is not supported in this archive format: "
"\"%s\" is required, but comes before \"%s\" in the archive file.\n",
th->targetFile, filename);
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 46ab6ee2bbc..3461f3e34c3 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -90,7 +90,7 @@ bool g_verbose; /* User wants verbose narration of our
/* various user-settable parameters */
bool schemaOnly;
bool dataOnly;
-int dumpSections; /* bitmask of chosen sections */
+int dumpSections; /* bitmask of chosen sections */
bool aclsSkip;
const char *lockWaitTimeout;
@@ -253,6 +253,7 @@ static const char *getAttrName(int attrnum, TableInfo *tblInfo);
static const char *fmtCopyColumnList(const TableInfo *ti);
static PGresult *ExecuteSqlQueryForSingleRow(Archive *fout, char *query);
+
int
main(int argc, char **argv)
{
@@ -499,7 +500,7 @@ main(int argc, char **argv)
break;
case 5: /* section */
- set_section(optarg, &dumpSections);
+ set_dump_section(optarg, &dumpSections);
break;
default:
@@ -529,19 +530,6 @@ main(int argc, char **argv)
if (dataOnly && schemaOnly)
exit_horribly(NULL, "options -s/--schema-only and -a/--data-only cannot be used together\n");
- if ((dataOnly || schemaOnly) && dumpSections != DUMP_UNSECTIONED)
- exit_horribly(NULL, "options -s/--schema-only and -a/--data-only cannot be used with --section\n");
-
- if (dataOnly)
- dumpSections = DUMP_DATA;
- else if (schemaOnly)
- dumpSections = DUMP_PRE_DATA | DUMP_POST_DATA;
- else if ( dumpSections != DUMP_UNSECTIONED)
- {
- dataOnly = dumpSections == DUMP_DATA;
- schemaOnly = !(dumpSections & DUMP_DATA);
- }
-
if (dataOnly && outputClean)
exit_horribly(NULL, "options -c/--clean and -a/--data-only cannot be used together\n");
@@ -739,31 +727,40 @@ main(int argc, char **argv)
dumpDumpableObject(fout, dobjs[i]);
/*
- * And finally we can do the actual output.
+ * Set up options info to ensure we dump what we want.
*/
- if (plainText)
- {
- ropt = NewRestoreOptions();
- ropt->filename = filename;
- ropt->dropSchema = outputClean;
- ropt->aclsSkip = aclsSkip;
- ropt->superuser = outputSuperuser;
- ropt->createDB = outputCreateDB;
- ropt->noOwner = outputNoOwner;
- ropt->noTablespace = outputNoTablespaces;
- ropt->disable_triggers = disable_triggers;
- ropt->use_setsessauth = use_setsessauth;
- ropt->dataOnly = dataOnly;
-
- if (compressLevel == -1)
- ropt->compression = 0;
- else
- ropt->compression = compressLevel;
+ ropt = NewRestoreOptions();
+ ropt->filename = filename;
+ ropt->dropSchema = outputClean;
+ ropt->dataOnly = dataOnly;
+ ropt->schemaOnly = schemaOnly;
+ ropt->dumpSections = dumpSections;
+ ropt->aclsSkip = aclsSkip;
+ ropt->superuser = outputSuperuser;
+ ropt->createDB = outputCreateDB;
+ ropt->noOwner = outputNoOwner;
+ ropt->noTablespace = outputNoTablespaces;
+ ropt->disable_triggers = disable_triggers;
+ ropt->use_setsessauth = use_setsessauth;
- ropt->suppressDumpWarnings = true; /* We've already shown them */
+ if (compressLevel == -1)
+ ropt->compression = 0;
+ else
+ ropt->compression = compressLevel;
- RestoreArchive(fout, ropt);
- }
+ ropt->suppressDumpWarnings = true; /* We've already shown them */
+
+ SetArchiveRestoreOptions(fout, ropt);
+
+ /*
+ * And finally we can do the actual output.
+ *
+ * Note: for non-plain-text output formats, the output file is written
+ * inside CloseArchive(). This is, um, bizarre; but not worth changing
+ * right now.
+ */
+ if (plainText)
+ RestoreArchive(fout);
CloseArchive(fout);
@@ -7084,28 +7081,6 @@ collectComments(Archive *fout, CommentItem **items)
static void
dumpDumpableObject(Archive *fout, DumpableObject *dobj)
{
-
- bool skip = false;
-
- switch (dobj->objType)
- {
- case DO_INDEX:
- case DO_TRIGGER:
- case DO_CONSTRAINT:
- case DO_FK_CONSTRAINT:
- case DO_RULE:
- skip = !(dumpSections & DUMP_POST_DATA);
- break;
- case DO_TABLE_DATA:
- skip = !(dumpSections & DUMP_DATA);
- break;
- default:
- skip = !(dumpSections & DUMP_PRE_DATA);
- }
-
- if (skip)
- return;
-
switch (dobj->objType)
{
case DO_NAMESPACE:
diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c
index d1a2ce36656..f3715271939 100644
--- a/src/bin/pg_dump/pg_restore.c
+++ b/src/bin/pg_dump/pg_restore.c
@@ -274,7 +274,7 @@ main(int argc, char **argv)
break;
case 3: /* section */
- set_section(optarg, &(opts->dumpSections));
+ set_dump_section(optarg, &(opts->dumpSections));
break;
default:
@@ -299,30 +299,6 @@ main(int argc, char **argv)
exit_nicely(1);
}
- if (opts->dataOnly && opts->schemaOnly)
- {
- fprintf(stderr, _("%s: options -s/--schema-only and -a/--data-only cannot be used together\n"),
- progname);
- exit_nicely(1);
- }
-
- if ((opts->dataOnly || opts->schemaOnly) && (opts->dumpSections != DUMP_UNSECTIONED))
- {
- fprintf(stderr, _("%s: options -s/--schema-only and -a/--data-only cannot be used with --section\n"),
- progname);
- exit_nicely(1);
- }
-
- if (opts->dataOnly)
- opts->dumpSections = DUMP_DATA;
- else if (opts->schemaOnly)
- opts->dumpSections = DUMP_PRE_DATA | DUMP_POST_DATA;
- else if ( opts->dumpSections != DUMP_UNSECTIONED)
- {
- opts->dataOnly = opts->dumpSections == DUMP_DATA;
- opts->schemaOnly = !(opts->dumpSections & DUMP_DATA);
- }
-
/* Should get at most one of -d and -f, else user is confused */
if (opts->dbname)
{
@@ -396,19 +372,14 @@ main(int argc, char **argv)
if (opts->tocFile)
SortTocFromFile(AH, opts);
- else if (opts->noDataForFailedTables)
- {
- /*
- * we implement this option by clearing idWanted entries, so must
- * create a dummy idWanted array if there wasn't a tocFile
- */
- InitDummyWantedList(AH, opts);
- }
if (opts->tocSummary)
PrintTOCSummary(AH, opts);
else
- RestoreArchive(AH, opts);
+ {
+ SetArchiveRestoreOptions(AH, opts);
+ RestoreArchive(AH);
+ }
/* done, print a summary of ignored errors */
if (AH->n_errors)