On Sat, November 12, 2011 8:56 pm, Andrew Dunstan wrote:
>
>
> On 08/26/2011 05:11 PM, Tom Lane wrote:
>> Alvaro Herrera<[email protected]> writes:
>>> The "--section=data --section=indexes" proposal seems very reasonable
>>> to
>>> me -- more so than "--sections='data indexes'".
>> +1 ... not only easier to code and less squishily defined, but more like
>> the existing precedent for other pg_dump switches, such as --table.
>>
>>
>
>
> Here is a patch for that for pg_dump. The sections provided for are
> pre-data, data and post-data, as discussed elsewhere. I still feel that
> anything finer grained should be handled via pg_restore's --use-list
> functionality. I'll provide a patch to do the same switch for pg_restore
> shortly.
>
> Adding to the commitfest.
>
Updated version with pg_restore included is attached.
cheers
andrew
*** a/doc/src/sgml/ref/pg_dump.sgml
--- b/doc/src/sgml/ref/pg_dump.sgml
***************
*** 116,124 **** PostgreSQL documentation
</para>
<para>
! This option is only meaningful for the plain-text format. For
! the archive formats, you can specify the option when you
! call <command>pg_restore</command>.
</para>
</listitem>
</varlistentry>
--- 116,122 ----
</para>
<para>
! This option is equivalent to specifying <option>--section=data</>.
</para>
</listitem>
</varlistentry>
***************
*** 404,413 **** PostgreSQL documentation
--- 402,431 ----
<para>
Dump only the object definitions (schema), not data.
</para>
+ <para>
+ This option is equivalent to specifying
+ <option>--section=pre-data --section=post-data</>.
+ </para>
</listitem>
</varlistentry>
<varlistentry>
+ <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.
+ </para>
+ <para>
+ Post-data items consist of definitions of indexes, triggers, rules
+ and constraints other than check constraints.
+ Pre-data items consist of all other data definition items.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>-S <replaceable class="parameter">username</replaceable></option></term>
<term><option>--superuser=<replaceable class="parameter">username</replaceable></option></term>
<listitem>
*** a/doc/src/sgml/ref/pg_restore.sgml
--- b/doc/src/sgml/ref/pg_restore.sgml
***************
*** 93,98 ****
--- 93,101 ----
<para>
Restore only the data, not the schema (data definitions).
</para>
+ <para>
+ This option is equivalent to specifying <option>--section=data</>.
+ </para>
</listitem>
</varlistentry>
***************
*** 359,364 ****
--- 362,371 ----
(Do not confuse this with the <option>--schema</> option, which
uses the word <quote>schema</> in a different meaning.)
</para>
+ <para>
+ This option is equivalent to specifying
+ <option>--section=pre-data --section=post-data</>.
+ </para>
</listitem>
</varlistentry>
***************
*** 505,510 ****
--- 512,533 ----
</varlistentry>
<varlistentry>
+ <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.
+ </para>
+ <para>
+ Post-data items consist of definitions of indexes, triggers, rules
+ and constraints other than check constraints.
+ Pre-data items consist of all other data definition items.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>--use-set-session-authorization</option></term>
<listitem>
<para>
*** a/src/bin/pg_dump/pg_backup.h
--- b/src/bin/pg_dump/pg_backup.h
***************
*** 69,74 **** typedef enum _teSection
--- 69,82 ----
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.
***************
*** 111,116 **** typedef struct _restoreOptions
--- 119,125 ----
int dropSchema;
char *filename;
int schemaOnly;
+ int dumpSections;
int verbose;
int aclsSkip;
int tocSummary;
*** a/src/bin/pg_dump/pg_backup_archiver.c
--- b/src/bin/pg_dump/pg_backup_archiver.c
***************
*** 665,670 **** NewRestoreOptions(void)
--- 665,671 ----
/* set any fields that shouldn't default to zeroes */
opts->format = archUnknown;
opts->promptPassword = TRI_DEFAULT;
+ opts->dumpSections = DUMP_UNSECTIONED;
return opts;
}
***************
*** 2163,2168 **** ReadToc(ArchiveHandle *AH)
--- 2164,2170 ----
int depIdx;
int depSize;
TocEntry *te;
+ bool in_post_data = false;
AH->tocCount = ReadInt(AH);
AH->maxDumpId = 0;
***************
*** 2228,2233 **** ReadToc(ArchiveHandle *AH)
--- 2230,2241 ----
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);
***************
*** 2377,2382 **** _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls)
--- 2385,2401 ----
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)
+ {
+ if (!(ropt->dumpSections & DUMP_POST_DATA) && te->inPostData)
+ return 0;
+ if (!(ropt->dumpSections & DUMP_PRE_DATA) && ! te->inPostData && strcmp(te->desc, "TABLE DATA") != 0)
+ return 0;
+ }
+
+
/* Check options for selective dump/restore */
if (ropt->schemaNames)
{
*** a/src/bin/pg_dump/pg_backup_archiver.h
--- b/src/bin/pg_dump/pg_backup_archiver.h
***************
*** 287,292 **** typedef struct _tocEntry
--- 287,295 ----
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 (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 */
*** a/src/bin/pg_dump/pg_dump.c
--- b/src/bin/pg_dump/pg_dump.c
***************
*** 91,96 **** PGconn *g_conn; /* the database connection */
--- 91,97 ----
/* various user-settable parameters */
bool schemaOnly;
bool dataOnly;
+ int dumpSections; /* bitmask of chosen sections */
bool aclsSkip;
const char *lockWaitTimeout;
***************
*** 247,253 **** static const char *fmtCopyColumnList(const TableInfo *ti);
static void do_sql_command(PGconn *conn, const char *query);
static void check_sql_result(PGresult *res, PGconn *conn, const char *query,
ExecStatusType expected);
!
int
main(int argc, char **argv)
--- 248,254 ----
static void do_sql_command(PGconn *conn, const char *query);
static void check_sql_result(PGresult *res, PGconn *conn, const char *query,
ExecStatusType expected);
! static void set_section(const char *arg);
int
main(int argc, char **argv)
***************
*** 330,335 **** main(int argc, char **argv)
--- 331,337 ----
{"quote-all-identifiers", no_argument, "e_all_identifiers, 1},
{"role", required_argument, NULL, 3},
{"serializable-deferrable", no_argument, &serializable_deferrable, 1},
+ {"section", required_argument, NULL, 5},
{"use-set-session-authorization", no_argument, &use_setsessauth, 1},
{"no-security-labels", no_argument, &no_security_labels, 1},
{"no-unlogged-table-data", no_argument, &no_unlogged_table_data, 1},
***************
*** 346,351 **** main(int argc, char **argv)
--- 348,354 ----
strcpy(g_opaque_type, "opaque");
dataOnly = schemaOnly = false;
+ dumpSections = DUMP_UNSECTIONED;
lockWaitTimeout = NULL;
progname = get_progname(argv[0]);
***************
*** 487,492 **** main(int argc, char **argv)
--- 490,499 ----
use_role = optarg;
break;
+ case 5: /* section */
+ set_section(optarg);
+ break;
+
default:
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
exit(1);
***************
*** 517,522 **** main(int argc, char **argv)
--- 524,545 ----
exit(1);
}
+ if ((dataOnly || schemaOnly) && dumpSections != DUMP_UNSECTIONED)
+ {
+ write_msg(NULL, "options -s/--schema-only and -a/--data-only cannot be used with --section\n");
+ exit(1);
+ }
+
+ 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)
{
write_msg(NULL, "options -c/--clean and -a/--data-only cannot be used together\n");
***************
*** 859,864 **** help(const char *progname)
--- 882,888 ----
printf(_(" --no-tablespaces do not dump tablespace assignments\n"));
printf(_(" --no-unlogged-table-data do not dump unlogged table data\n"));
printf(_(" --quote-all-identifiers quote all identifiers, even if not key words\n"));
+ printf(_(" --section=SECTION dump named section (pre-data, data or post-data)\n"));
printf(_(" --serializable-deferrable wait until the dump can run without anomalies\n"));
printf(_(" --use-set-session-authorization\n"
" use SET SESSION AUTHORIZATION commands instead of\n"
***************
*** 7038,7043 **** collectComments(Archive *fout, CommentItem **items)
--- 7062,7089 ----
static void
dumpDumpableObject(Archive *fout, DumpableObject *dobj)
{
+
+ int skip = 0;
+
+ 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:
***************
*** 14402,14404 **** check_sql_result(PGresult *res, PGconn *conn, const char *query,
--- 14448,14473 ----
write_msg(NULL, "The command was: %s\n", query);
exit_nicely();
}
+
+ static void
+ set_section (const char *arg)
+ {
+ /* 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(1);
+ }
+ }
*** a/src/bin/pg_dump/pg_restore.c
--- b/src/bin/pg_dump/pg_restore.c
***************
*** 61,66 **** extern int optind;
--- 61,67 ----
static void usage(const char *progname);
+ static void set_section (int *dumpSections, const char *arg);
typedef struct option optType;
***************
*** 116,121 **** main(int argc, char **argv)
--- 117,123 ----
{"no-data-for-failed-tables", no_argument, &no_data_for_failed_tables, 1},
{"no-tablespaces", no_argument, &outputNoTablespaces, 1},
{"role", required_argument, NULL, 2},
+ {"section", required_argument, NULL, 3},
{"use-set-session-authorization", no_argument, &use_setsessauth, 1},
{"no-security-labels", no_argument, &no_security_labels, 1},
***************
*** 270,275 **** main(int argc, char **argv)
--- 272,281 ----
opts->use_role = optarg;
break;
+ case 3: /* section */
+ set_section(&(opts->dumpSections), optarg);
+ break;
+
default:
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
exit(1);
***************
*** 292,297 **** main(int argc, char **argv)
--- 298,327 ----
exit(1);
}
+ if (opts->dataOnly && opts->schemaOnly)
+ {
+ fprintf(stderr, _("%s: options -s/--schema-only and -a/--data-only cannot be used together\n"),
+ progname);
+ exit(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(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)
{
***************
*** 432,437 **** usage(const char *progname)
--- 462,468 ----
" created\n"));
printf(_(" --no-security-labels do not restore security labels\n"));
printf(_(" --no-tablespaces do not restore tablespace assignments\n"));
+ printf(_(" --section=SECTION restore named section (pre-data, data or post-data)\n"));
printf(_(" --use-set-session-authorization\n"
" use SET SESSION AUTHORIZATION commands instead of\n"
" ALTER OWNER commands to set ownership\n"));
***************
*** 447,449 **** usage(const char *progname)
--- 478,503 ----
printf(_("\nIf no input file name is supplied, then standard input is used.\n\n"));
printf(_("Report bugs to <[email protected]>.\n"));
}
+
+ static void
+ set_section (int *dumpSections, const char *arg)
+ {
+ /* 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(1);
+ }
+ }
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers