On Sat, November 12, 2011 8:56 pm, Andrew Dunstan wrote: > > > On 08/26/2011 05:11 PM, Tom Lane wrote: >> Alvaro Herrera<alvhe...@commandprompt.com> 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 <pgsql-b...@postgresql.org>.\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 (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers