From b60221152267052914f431425791c9733110fc0f Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Sun, 13 Nov 2011 09:22:54 -0500 Subject: [PATCH 1/7] working --- src/bin/pg_dump/pg_backup.h | 8 +++++ src/bin/pg_dump/pg_dump.c | 70 ++++++++++++++++++++++++++++++++++++- 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h index ce12a41ce3..c1a5967055 100644 --- a/src/bin/pg_dump/pg_backup.h +++ b/src/bin/pg_dump/pg_backup.h @@ -69,6 +69,14 @@ 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. diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 973f0b335d..da2ba04eed 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -91,6 +91,7 @@ PGconn *g_conn; /* the database connection */ /* various user-settable parameters */ bool schemaOnly; bool dataOnly; +int dumpSections; /* bitmask of chosen sections */ bool aclsSkip; const char *lockWaitTimeout; @@ -247,7 +248,7 @@ 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); - +static void set_section(const char *arg); int main(int argc, char **argv) @@ -330,6 +331,7 @@ main(int argc, char **argv) {"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,6 +348,7 @@ main(int argc, char **argv) strcpy(g_opaque_type, "opaque"); dataOnly = schemaOnly = false; + dumpSections = DUMP_UNSECTIONED; lockWaitTimeout = NULL; progname = get_progname(argv[0]); @@ -487,6 +490,10 @@ main(int argc, char **argv) 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,6 +524,22 @@ main(int argc, char **argv) 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,6 +882,7 @@ help(const char *progname) 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,6 +7062,28 @@ collectComments(Archive *fout, CommentItem **items) 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,3 +14448,25 @@ check_sql_result(PGresult *res, PGconn *conn, const char *query, 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); + } +} From abe5686ca40555d92d8410fc05b9f8fb5181cbef Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Sun, 13 Nov 2011 10:00:57 -0500 Subject: [PATCH 2/7] add docs --- doc/src/sgml/ref/pg_dump.sgml | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index f6f33de7e7..ca4890c1de 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -116,9 +116,7 @@ PostgreSQL documentation - This option is only meaningful for the plain-text format. For - the archive formats, you can specify the option when you - call pg_restore. + This option is equivalent to specifying @@ -404,9 +402,29 @@ PostgreSQL documentation Dump only the object definitions (schema), not data. + + This option is equivalent to specifying + + + + + + Only dump the named section. The name can be one of + + 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. + + + + From d37aa063955d466a72b93137097d9187d4438e04 Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Sun, 13 Nov 2011 10:03:06 -0500 Subject: [PATCH 3/7] add missing paren --- src/bin/pg_dump/pg_dump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index da2ba04eed..ea3941edfb 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -882,7 +882,7 @@ help(const char *progname) 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(_(" --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" From c50a87d641de96277faa720dca7d236072738264 Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Sun, 13 Nov 2011 10:29:46 -0500 Subject: [PATCH 4/7] add restore infrastructure --- src/bin/pg_dump/pg_backup.h | 1 + src/bin/pg_dump/pg_backup_archiver.c | 8 ++++++++ src/bin/pg_dump/pg_backup_archiver.h | 3 +++ 3 files changed, 12 insertions(+) diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h index c1a5967055..bb46fa678b 100644 --- a/src/bin/pg_dump/pg_backup.h +++ b/src/bin/pg_dump/pg_backup.h @@ -119,6 +119,7 @@ typedef struct _restoreOptions int dropSchema; char *filename; int schemaOnly; + int dumpSections; int verbose; int aclsSkip; int tocSummary; diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index f47af264cb..abb042763a 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -665,6 +665,7 @@ NewRestoreOptions(void) /* set any fields that shouldn't default to zeroes */ opts->format = archUnknown; opts->promptPassword = TRI_DEFAULT; + opts->dumpSections = DUMP_UNSECTIONED; return opts; } @@ -2163,6 +2164,7 @@ ReadToc(ArchiveHandle *AH) int depIdx; int depSize; TocEntry *te; + bool in_post_data = false; AH->tocCount = ReadInt(AH); AH->maxDumpId = 0; @@ -2228,6 +2230,12 @@ 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); diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h index 8a3a6f9e22..7712a42722 100644 --- a/src/bin/pg_dump/pg_backup_archiver.h +++ b/src/bin/pg_dump/pg_backup_archiver.h @@ -287,6 +287,9 @@ 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 (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 */ From 83aa5a9b2685a5f957e943e66c5af78cc091a801 Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Sun, 13 Nov 2011 10:40:31 -0500 Subject: [PATCH 5/7] fix indentation --- src/bin/pg_dump/pg_dump.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index ea3941edfb..12bb73afe6 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -14449,7 +14449,8 @@ check_sql_result(PGresult *res, PGconn *conn, const char *query, exit_nicely(); } -static void set_section (const char *arg) +static void +set_section (const char *arg) { /* if this is the first, clear all the bits */ if (dumpSections == DUMP_UNSECTIONED) From 9052cff11d04f7351d4ad5f8a100ad806f04d8ce Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Sun, 13 Nov 2011 11:07:27 -0500 Subject: [PATCH 6/7] add pg_restore logic --- src/bin/pg_dump/pg_backup_archiver.c | 11 ++++++ src/bin/pg_dump/pg_restore.c | 57 ++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index abb042763a..b0f4c35520 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -2385,6 +2385,17 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls) 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) { diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c index 7731d2540c..bd5700b59c 100644 --- a/src/bin/pg_dump/pg_restore.c +++ b/src/bin/pg_dump/pg_restore.c @@ -61,6 +61,7 @@ extern int optind; static void usage(const char *progname); +static void set_section (int *dumpSections, const char *arg); typedef struct option optType; @@ -116,6 +117,7 @@ main(int argc, char **argv) {"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,6 +272,10 @@ main(int argc, char **argv) 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,6 +298,33 @@ main(int argc, char **argv) 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); + } + + + fprintf(stderr,"dumpsection: %d, dataOnly: %d, schemaOnly: %d\n", opts->dumpSections, opts->dataOnly, opts->schemaOnly); + /* Should get at most one of -d and -f, else user is confused */ if (opts->dbname) { @@ -432,6 +465,7 @@ usage(const char *progname) " 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,3 +481,26 @@ usage(const char *progname) printf(_("\nIf no input file name is supplied, then standard input is used.\n\n")); printf(_("Report bugs to .\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); + } +} From b6279382b9452b6d16beb70adce74e64c018ca60 Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Tue, 15 Nov 2011 16:11:04 -0500 Subject: [PATCH 7/7] version good, including restore --- doc/src/sgml/ref/pg_restore.sgml | 23 +++++++++++++++++++++++ src/bin/pg_dump/pg_restore.c | 3 --- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/doc/src/sgml/ref/pg_restore.sgml b/doc/src/sgml/ref/pg_restore.sgml index be11d176cd..85ee22d48b 100644 --- a/doc/src/sgml/ref/pg_restore.sgml +++ b/doc/src/sgml/ref/pg_restore.sgml @@ -93,6 +93,9 @@ Restore only the data, not the schema (data definitions). + + This option is equivalent to specifying @@ -359,6 +362,10 @@ (Do not confuse this with the