*** a/src/bin/pg_dump/pg_backup.h --- b/src/bin/pg_dump/pg_backup.h *************** *** 143,148 **** typedef struct _restoreOptions --- 143,149 ---- int number_of_jobs; bool *idWanted; /* array showing which dump IDs to emit */ + int split_files; /* --split option, split objects into separate files */ } RestoreOptions; /* *** a/src/bin/pg_dump/pg_backup_archiver.c --- b/src/bin/pg_dump/pg_backup_archiver.c *************** *** 27,32 **** --- 27,33 ---- #include #include #include + #include #ifdef WIN32 #include *************** *** 2830,2835 **** _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat --- 2831,2906 ---- return; } + /* + * Split object into separate file, + * if the --split option is enabled and, + * if the object has an oid. + */ + if (ropt->split_files && te->catalogId.oid) + { + char splitFilename[1024]; + char *tag; + char *tagArgPos; + char *desc; + char *descSpacePos; + mode_t omode; + + /* + * Strip eventual argument part from "tag" (e.g. the name of functions) + * Example: "foobar(_arg1 int, _arg2 int)" --> "foobar" + */ + tagArgPos = strstr(te->tag,"("); + if (tagArgPos == NULL) + tag = strdup(te->tag); + else + tag = strndup(te->tag, tagArgPos - te->tag); + + desc = strdup(te->desc); + descSpacePos = strstr(desc," "); + /* + * Replace " " with "_" in "desc" + * Example: "FK CONSTRAINT" --> "FK_CONSTRAINT" + */ + while ((descSpacePos = strstr(desc, " ")) != NULL) + { + char *dup = strdup(desc); + strlcpy(desc, dup, descSpacePos - desc + 1); + strcat(desc, "_"); + strcat(desc, dup + (descSpacePos - desc) + strlen("_")); + free(dup); + } + + /* + * Build path consisting of [filename]-split/[desc]/[tag]/[oid].sql + * Create the directories + * Example: dumpfile-split/FUNCTION/foobar/12345.sql + */ + omode = S_IRWXU | S_IRWXG | S_IRWXO; + snprintf(splitFilename, 1024, "%s-split", ropt->filename); + mkdir(splitFilename, omode); + snprintf(splitFilename, 1024, "%s-split/%s", ropt->filename, desc); + mkdir(splitFilename, omode); + snprintf(splitFilename, 1024, "%s-split/%s/%s", ropt->filename, desc, tag); + mkdir(splitFilename, omode); + snprintf(splitFilename, 1024, "%s-split/%s/%s/%d.sql", ropt->filename, desc, tag, te->catalogId.oid); + + /* Add \i to main dump file */ + ahprintf(AH, "\\i %s\n", splitFilename); + + /* + * Close the normal file handle to which non-splittable + * objects are written. + * + * Open split file handle for splitFilename. + * + * In the end of the function, + * the split file handle will be closed, and + * the normal file handle will be reopened again. + */ + fclose(AH->OF); + AH->OF = fopen(splitFilename, PG_BINARY_A); + } + /* Select owner, schema, and tablespace as necessary */ _becomeOwner(AH, te); _selectOutputSchema(AH, te->namespace); *************** *** 2960,2965 **** _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat --- 3031,3046 ---- free(AH->currUser); AH->currUser = NULL; } + + /* + * If we are using the --split option, + * close the split file handle, and reopen the normal file handle. + */ + if (ropt->split_files && te->catalogId.oid) + { + fclose(AH->OF); + AH->OF = fopen(ropt->filename, PG_BINARY_A); + } } void *** a/src/bin/pg_dump/pg_dump.c --- b/src/bin/pg_dump/pg_dump.c *************** *** 134,139 **** static int disable_dollar_quoting = 0; --- 134,140 ---- static int dump_inserts = 0; static int column_inserts = 0; static int no_security_label = 0; + static int split_files = 0; static void help(const char *progname); *************** *** 316,321 **** main(int argc, char **argv) --- 317,323 ---- {"role", required_argument, NULL, 3}, {"use-set-session-authorization", no_argument, &use_setsessauth, 1}, {"no-security-label", no_argument, &no_security_label, 1}, + {"split", no_argument, &split_files, 1}, {NULL, 0, NULL, 0} }; *************** *** 804,809 **** main(int argc, char **argv) --- 806,812 ---- ropt->disable_triggers = disable_triggers; ropt->use_setsessauth = use_setsessauth; ropt->dataOnly = dataOnly; + ropt->split_files = split_files; if (compressLevel == -1) ropt->compression = 0; *************** *** 836,841 **** help(const char *progname) --- 839,845 ---- printf(_(" -v, --verbose verbose mode\n")); printf(_(" -Z, --compress=0-9 compression level for compressed formats\n")); printf(_(" --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n")); + printf(_(" --split split objects into separate plain text files\n")); printf(_(" --help show this help, then exit\n")); printf(_(" --version output version information, then exit\n"));