Re-sending post as discussed with Bruce... On Sun, 2008-03-23 at 12:45 -0300, Alvaro Herrera wrote: > Bruce Momjian wrote: > > > > Added to TODO: > > > > o Allow pre/data/post files when dumping a single object, for > > performance reasons > > > > http://archives.postgresql.org/pgsql-hackers/2008-02/msg00205.php > > "When dumping a single object"?? Do you mean database?
It would be for whatever set of objects are specified through the use of databases, table include/exclude switches. I've written a patch that implements these new switches on the commands as shown pg_dump --schema-pre-load pg_dump --schema-post-load pg_restore --schema-pre-load pg_restore --schema-post-load I have not implemented --schema-pre-file=xxx style because they don't make any sense when using pg_restore in direct database connection mode. On reflection I don't see any particular need to produce multiple files as output, which just complicates an already horrendous user interface. This is a minimal set of changes and includes nothing at all about directories, parallelisation in the code etc.. This has the following use cases amongst others... * dump everything to a file, then use pg_restore first --schema-pre-load and then --data-only directly into the database, then pg_restore --schema-post-load to a file so we can edit that file into multiple pieces to allow index creation in parallel * dump of database into multiple files by manually specifying which tables go where, then reload in parallel using multiple psql sessions The patch tests OK after some testing, though without a test suite that probably isn't more than a few percentage points of all the possible code paths. There are no docs for it, as yet. --- Further thinking on this.... Some further refinement might replace --data-only and --schema-only with --want-schema-pre --want-data --want-schema-post --want-schema (same as --want-schema-pre --want-schema-post) These could be used together e.g. --want-schema-pre --want-data whereas the existing --data-only type switches cannot. Which would be a straightforward and useful change to the enclosed patch. That way of doing things is hierarchically extensible to include further subdivisions of the set of SQL commands produced, e.g. divide --want-post-schema into objects required to support various inter-table dependencies and those that don't such as additional indexes. I don't personally think we need that though. Comments? -- Simon Riggs 2ndQuadrant http://www.2ndQuadrant.com
Index: src/bin/pg_dump/pg_backup.h =================================================================== RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/bin/pg_dump/pg_backup.h,v retrieving revision 1.45 diff -c -r1.45 pg_backup.h *** src/bin/pg_dump/pg_backup.h 25 Jan 2007 03:30:43 -0000 1.45 --- src/bin/pg_dump/pg_backup.h 20 Mar 2008 11:48:34 -0000 *************** *** 88,94 **** int use_setsessauth;/* Use SET SESSION AUTHORIZATION commands * instead of OWNER TO */ char *superuser; /* Username to use as superuser */ ! int dataOnly; int dropSchema; char *filename; int schemaOnly; --- 88,94 ---- int use_setsessauth;/* Use SET SESSION AUTHORIZATION commands * instead of OWNER TO */ char *superuser; /* Username to use as superuser */ ! int dumpObjFlags; /* which objects types to dump */ int dropSchema; char *filename; int schemaOnly; Index: src/bin/pg_dump/pg_backup_archiver.c =================================================================== RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v retrieving revision 1.152 diff -c -r1.152 pg_backup_archiver.c *** src/bin/pg_dump/pg_backup_archiver.c 14 Jan 2008 19:27:41 -0000 1.152 --- src/bin/pg_dump/pg_backup_archiver.c 20 Mar 2008 11:48:34 -0000 *************** *** 56,62 **** 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 void _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt); static void _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt); static TocEntry *getTocEntryByDumpId(ArchiveHandle *AH, DumpId id); --- 56,62 ---- static void _selectTablespace(ArchiveHandle *AH, const char *tablespace); static void processEncodingEntry(ArchiveHandle *AH, TocEntry *te); static void processStdStringsEntry(ArchiveHandle *AH, TocEntry *te); ! static int _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls); static void _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt); static void _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt); static TocEntry *getTocEntryByDumpId(ArchiveHandle *AH, DumpId id); *************** *** 129,135 **** { ArchiveHandle *AH = (ArchiveHandle *) AHX; TocEntry *te; ! teReqs reqs; OutputContext sav; bool defnDumped; --- 129,135 ---- { ArchiveHandle *AH = (ArchiveHandle *) AHX; TocEntry *te; ! int reqs; OutputContext sav; bool defnDumped; *************** *** 175,193 **** * Work out if we have an implied data-only restore. This can happen if * the dump was data only or if the user has used a toc list to exclude * all of the schema data. All we do is look for schema entries - if none ! * are found then we set the dataOnly flag. * ! * We could scan for wanted TABLE entries, but that is not the same as ! * dataOnly. At this stage, it seems unnecessary (6-Mar-2001). */ ! if (!ropt->dataOnly) { int impliedDataOnly = 1; for (te = AH->toc->next; te != AH->toc; te = te->next) { reqs = _tocEntryRequired(te, ropt, true); ! if ((reqs & REQ_SCHEMA) != 0) { /* It's schema, and it's wanted */ impliedDataOnly = 0; break; --- 175,193 ---- * Work out if we have an implied data-only restore. This can happen if * the dump was data only or if the user has used a toc list to exclude * all of the schema data. All we do is look for schema entries - if none ! * are found then say we only want DATA type objects. * ! * We could scan for wanted TABLE entries, but that is not the same. ! * At this stage, it seems unnecessary (6-Mar-2001). */ ! if (!WANT_DATA(ropt->dumpObjFlags)) { int impliedDataOnly = 1; for (te = AH->toc->next; te != AH->toc; te = te->next) { reqs = _tocEntryRequired(te, ropt, true); ! if (WANT_PRE_SCHEMA(reqs) || WANT_POST_SCHEMA(reqs)) { /* It's schema, and it's wanted */ impliedDataOnly = 0; break; *************** *** 195,201 **** } if (impliedDataOnly) { ! ropt->dataOnly = impliedDataOnly; ahlog(AH, 1, "implied data-only restore\n"); } } --- 195,201 ---- } if (impliedDataOnly) { ! ropt->dumpObjFlags = REQ_DATA; ahlog(AH, 1, "implied data-only restore\n"); } } *************** *** 236,242 **** AH->currentTE = te; reqs = _tocEntryRequired(te, ropt, false /* needn't drop ACLs */ ); ! if (((reqs & REQ_SCHEMA) != 0) && te->dropStmt) { /* We want the schema */ ahlog(AH, 1, "dropping %s %s\n", te->desc, te->tag); --- 236,242 ---- AH->currentTE = te; reqs = _tocEntryRequired(te, ropt, false /* needn't drop ACLs */ ); ! if (((reqs & REQ_PRE_SCHEMA) != 0) && te->dropStmt) { /* We want the schema */ ahlog(AH, 1, "dropping %s %s\n", te->desc, te->tag); *************** *** 278,284 **** /* Dump any relevant dump warnings to stderr */ if (!ropt->suppressDumpWarnings && strcmp(te->desc, "WARNING") == 0) { ! if (!ropt->dataOnly && te->defn != NULL && strlen(te->defn) != 0) write_msg(modulename, "warning from original dump file: %s\n", te->defn); else if (te->copyStmt != NULL && strlen(te->copyStmt) != 0) write_msg(modulename, "warning from original dump file: %s\n", te->copyStmt); --- 278,284 ---- /* Dump any relevant dump warnings to stderr */ if (!ropt->suppressDumpWarnings && strcmp(te->desc, "WARNING") == 0) { ! if (!WANT_DATA(ropt->dumpObjFlags) && te->defn != NULL && strlen(te->defn) != 0) write_msg(modulename, "warning from original dump file: %s\n", te->defn); else if (te->copyStmt != NULL && strlen(te->copyStmt) != 0) write_msg(modulename, "warning from original dump file: %s\n", te->copyStmt); *************** *** 286,292 **** defnDumped = false; ! if ((reqs & REQ_SCHEMA) != 0) /* We want the schema */ { ahlog(AH, 1, "creating %s %s\n", te->desc, te->tag); --- 286,293 ---- defnDumped = false; ! if ((WANT_PRE_SCHEMA(reqs) && WANT_PRE_SCHEMA(ropt->dumpObjFlags)) || ! (WANT_POST_SCHEMA(reqs) && WANT_POST_SCHEMA(ropt->dumpObjFlags))) /* We want the schema */ { ahlog(AH, 1, "creating %s %s\n", te->desc, te->tag); *************** *** 331,337 **** /* * If we have a data component, then process it */ ! if ((reqs & REQ_DATA) != 0) { /* * hadDumper will be set if there is genuine data component for --- 332,338 ---- /* * If we have a data component, then process it */ ! if (WANT_DATA(reqs)) { /* * hadDumper will be set if there is genuine data component for *************** *** 343,349 **** /* * If we can output the data, then restore it. */ ! if (AH->PrintTocDataPtr !=NULL && (reqs & REQ_DATA) != 0) { #ifndef HAVE_LIBZ if (AH->compression != 0) --- 344,350 ---- /* * If we can output the data, then restore it. */ ! if (AH->PrintTocDataPtr !=NULL && WANT_DATA(reqs)) { #ifndef HAVE_LIBZ if (AH->compression != 0) *************** *** 415,421 **** /* Work out what, if anything, we want from this entry */ reqs = _tocEntryRequired(te, ropt, true); ! if ((reqs & REQ_SCHEMA) != 0) /* We want the schema */ { ahlog(AH, 1, "setting owner and privileges for %s %s\n", te->desc, te->tag); --- 416,422 ---- /* Work out what, if anything, we want from this entry */ reqs = _tocEntryRequired(te, ropt, true); ! if (WANT_PRE_SCHEMA(reqs)) /* We want the schema */ { ahlog(AH, 1, "setting owner and privileges for %s %s\n", te->desc, te->tag); *************** *** 473,479 **** _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt) { /* This hack is only needed in a data-only restore */ ! if (!ropt->dataOnly || !ropt->disable_triggers) return; ahlog(AH, 1, "disabling triggers for %s\n", te->tag); --- 474,480 ---- _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt) { /* This hack is only needed in a data-only restore */ ! if (!WANT_DATA(ropt->dumpObjFlags) || !ropt->disable_triggers) return; ahlog(AH, 1, "disabling triggers for %s\n", te->tag); *************** *** 499,505 **** _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt) { /* This hack is only needed in a data-only restore */ ! if (!ropt->dataOnly || !ropt->disable_triggers) return; ahlog(AH, 1, "enabling triggers for %s\n", te->tag); --- 500,506 ---- _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt) { /* This hack is only needed in a data-only restore */ ! if (!WANT_DATA(ropt->dumpObjFlags) || !ropt->disable_triggers) return; ahlog(AH, 1, "enabling triggers for %s\n", te->tag); *************** *** 1321,1327 **** return NULL; } ! teReqs TocIDRequired(ArchiveHandle *AH, DumpId id, RestoreOptions *ropt) { TocEntry *te = getTocEntryByDumpId(AH, id); --- 1322,1328 ---- return NULL; } ! int TocIDRequired(ArchiveHandle *AH, DumpId id, RestoreOptions *ropt) { TocEntry *te = getTocEntryByDumpId(AH, id); *************** *** 2026,2035 **** te->defn); } ! static teReqs _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls) { ! teReqs res = REQ_ALL; /* ENCODING and STDSTRINGS items are dumped specially, so always reject */ if (strcmp(te->desc, "ENCODING") == 0 || --- 2027,2036 ---- te->defn); } ! static int _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls) { ! int res = ropt->dumpObjFlags; /* ENCODING and STDSTRINGS items are dumped specially, so always reject */ if (strcmp(te->desc, "ENCODING") == 0 || *************** *** 2109,2125 **** if ((strcmp(te->desc, "<Init>") == 0) && (strcmp(te->tag, "Max OID") == 0)) return 0; - /* Mask it if we only want schema */ - if (ropt->schemaOnly) - res = res & REQ_SCHEMA; - - /* Mask it we only want data */ - if (ropt->dataOnly) - res = res & REQ_DATA; - /* Mask it if we don't have a schema contribution */ if (!te->defn || strlen(te->defn) == 0) ! res = res & ~REQ_SCHEMA; /* Finally, if there's a per-ID filter, limit based on that as well */ if (ropt->idWanted && !ropt->idWanted[te->dumpId - 1]) --- 2110,2118 ---- if ((strcmp(te->desc, "<Init>") == 0) && (strcmp(te->tag, "Max OID") == 0)) return 0; /* Mask it if we don't have a schema contribution */ if (!te->defn || strlen(te->defn) == 0) ! res = res & ~(REQ_PRE_SCHEMA | REQ_POST_SCHEMA); /* Finally, if there's a per-ID filter, limit based on that as well */ if (ropt->idWanted && !ropt->idWanted[te->dumpId - 1]) Index: src/bin/pg_dump/pg_backup_archiver.h =================================================================== RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/bin/pg_dump/pg_backup_archiver.h,v retrieving revision 1.76 diff -c -r1.76 pg_backup_archiver.h *** src/bin/pg_dump/pg_backup_archiver.h 7 Nov 2007 12:24:24 -0000 1.76 --- src/bin/pg_dump/pg_backup_archiver.h 20 Mar 2008 11:48:34 -0000 *************** *** 158,169 **** STAGE_FINALIZING } ArchiverStage; ! typedef enum ! { ! REQ_SCHEMA = 1, ! REQ_DATA = 2, ! REQ_ALL = REQ_SCHEMA + REQ_DATA ! } teReqs; typedef struct _archiveHandle { --- 158,173 ---- STAGE_FINALIZING } ArchiverStage; ! #define REQ_PRE_SCHEMA (1 << 0) ! #define REQ_DATA (1 << 1) ! #define REQ_POST_SCHEMA (1 << 2) ! #define REQ_ALL (REQ_PRE_SCHEMA + REQ_DATA + REQ_POST_SCHEMA) ! ! #define WANT_PRE_SCHEMA(req) ((req & REQ_PRE_SCHEMA) == REQ_PRE_SCHEMA) ! #define WANT_DATA(req) ((req & REQ_DATA) == REQ_DATA) ! #define WANT_POST_SCHEMA(req) ((req & REQ_POST_SCHEMA) == REQ_POST_SCHEMA) ! #define WANT_ALL(req) ((req & REQ_ALL) == REQ_ALL) ! typedef struct _archiveHandle { *************** *** 317,323 **** extern void ReadToc(ArchiveHandle *AH); extern void WriteDataChunks(ArchiveHandle *AH); ! extern teReqs TocIDRequired(ArchiveHandle *AH, DumpId id, RestoreOptions *ropt); extern bool checkSeek(FILE *fp); #define appendStringLiteralAHX(buf,str,AH) \ --- 321,327 ---- extern void ReadToc(ArchiveHandle *AH); extern void WriteDataChunks(ArchiveHandle *AH); ! extern int TocIDRequired(ArchiveHandle *AH, DumpId id, RestoreOptions *ropt); extern bool checkSeek(FILE *fp); #define appendStringLiteralAHX(buf,str,AH) \ Index: src/bin/pg_dump/pg_dump.c =================================================================== RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/bin/pg_dump/pg_dump.c,v retrieving revision 1.482 diff -c -r1.482 pg_dump.c *** src/bin/pg_dump/pg_dump.c 30 Jan 2008 18:35:55 -0000 1.482 --- src/bin/pg_dump/pg_dump.c 20 Mar 2008 11:48:34 -0000 *************** *** 78,83 **** --- 78,90 ---- bool dataOnly; bool aclsSkip; + static int use_schemaPreLoadOnly; + static int use_schemaPostLoadOnly; + + /* groups of objects: default is we dump all groups */ + + int dumpObjFlags; + /* subquery used to convert user ID (eg, datdba) to user name */ static const char *username_subquery; *************** *** 214,219 **** --- 221,227 ---- int numTables; DumpableObject **dobjs; int numObjs; + int num_object_groups = 0; int i; bool force_password = false; int compressLevel = -1; *************** *** 266,271 **** --- 274,281 ---- */ {"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1}, {"disable-triggers", no_argument, &disable_triggers, 1}, + {"schema-pre-load", no_argument, &use_schemaPreLoadOnly, 1}, + {"schema-post-load", no_argument, &use_schemaPostLoadOnly, 1}, {"use-set-session-authorization", no_argument, &use_setsessauth, 1}, {NULL, 0, NULL, 0} *************** *** 456,467 **** if (optind < argc) dbname = argv[optind]; ! if (dataOnly && schemaOnly) { ! write_msg(NULL, "options -s/--schema-only and -a/--data-only cannot be used together\n"); exit(1); } if (dataOnly && outputClean) { write_msg(NULL, "options -c/--clean and -a/--data-only cannot be used together\n"); --- 466,506 ---- if (optind < argc) dbname = argv[optind]; ! /* ! * Look for conflicting options relating to object types ! */ ! if (dataOnly) ! num_object_groups++; ! if (schemaOnly) ! num_object_groups++; ! if (use_schemaPreLoadOnly == 1) ! num_object_groups++; ! if (use_schemaPostLoadOnly == 1) ! num_object_groups++; ! ! if (num_object_groups > 1) { ! write_msg(NULL, "multiple object groups cannot be used together\n"); exit(1); } + /* + * Decide which of the object groups we will dump + */ + dumpObjFlags = REQ_ALL; + + if (dataOnly) + dumpObjFlags = REQ_DATA; + + if (use_schemaPreLoadOnly == 1) + dumpObjFlags = REQ_PRE_SCHEMA; + + if (use_schemaPostLoadOnly == 1) + dumpObjFlags = REQ_POST_SCHEMA; + + if (schemaOnly) + dumpObjFlags = (REQ_PRE_SCHEMA | REQ_POST_SCHEMA); + if (dataOnly && outputClean) { write_msg(NULL, "options -c/--clean and -a/--data-only cannot be used together\n"); *************** *** 626,632 **** * Dumping blobs is now default unless we saw an inclusion switch or -s * ... but even if we did see one of these, -b turns it back on. */ ! if (include_everything && !schemaOnly) outputBlobs = true; /* --- 665,671 ---- * Dumping blobs is now default unless we saw an inclusion switch or -s * ... but even if we did see one of these, -b turns it back on. */ ! if (include_everything && WANT_PRE_SCHEMA(dumpObjFlags)) outputBlobs = true; /* *************** *** 635,641 **** */ tblinfo = getSchemaData(&numTables); ! if (!schemaOnly) getTableData(tblinfo, numTables, oids); if (outputBlobs && hasBlobs(g_fout)) --- 674,680 ---- */ tblinfo = getSchemaData(&numTables); ! if (WANT_DATA(dumpObjFlags)) getTableData(tblinfo, numTables, oids); if (outputBlobs && hasBlobs(g_fout)) *************** *** 689,695 **** dumpStdStrings(g_fout); /* The database item is always next, unless we don't want it at all */ ! if (include_everything && !dataOnly) dumpDatabase(g_fout); /* Now the rearrangeable objects. */ --- 728,734 ---- dumpStdStrings(g_fout); /* The database item is always next, unless we don't want it at all */ ! if (include_everything && WANT_DATA(dumpObjFlags)) dumpDatabase(g_fout); /* Now the rearrangeable objects. */ *************** *** 710,716 **** ropt->noOwner = outputNoOwner; ropt->disable_triggers = disable_triggers; ropt->use_setsessauth = use_setsessauth; ! ropt->dataOnly = dataOnly; if (compressLevel == -1) ropt->compression = 0; --- 749,755 ---- ropt->noOwner = outputNoOwner; ropt->disable_triggers = disable_triggers; ropt->use_setsessauth = use_setsessauth; ! ropt->dumpObjFlags = dumpObjFlags; if (compressLevel == -1) ropt->compression = 0; *************** *** 3299,3305 **** continue; /* Ignore indexes of tables not to be dumped */ ! if (!tbinfo->dobj.dump) continue; if (g_verbose) --- 3338,3344 ---- continue; /* Ignore indexes of tables not to be dumped */ ! if (!tbinfo->dobj.dump || !WANT_POST_SCHEMA(dumpObjFlags)) continue; if (g_verbose) *************** *** 5034,5040 **** int ncomments; /* Comments are SCHEMA not data */ ! if (dataOnly) return; /* Search for comments associated with catalogId, using table */ --- 5073,5079 ---- int ncomments; /* Comments are SCHEMA not data */ ! if (!WANT_PRE_SCHEMA(dumpObjFlags)) return; /* Search for comments associated with catalogId, using table */ *************** *** 5085,5091 **** PQExpBuffer target; /* Comments are SCHEMA not data */ ! if (dataOnly) return; /* Search for comments associated with relation, using table */ --- 5124,5130 ---- PQExpBuffer target; /* Comments are SCHEMA not data */ ! if (!WANT_PRE_SCHEMA(dumpObjFlags)) return; /* Search for comments associated with relation, using table */ *************** *** 5437,5443 **** char *qnspname; /* Skip if not to be dumped */ ! if (!nspinfo->dobj.dump || dataOnly) return; /* don't dump dummy namespace from pre-7.3 source */ --- 5476,5482 ---- char *qnspname; /* Skip if not to be dumped */ ! if (!nspinfo->dobj.dump || !WANT_PRE_SCHEMA(dumpObjFlags)) return; /* don't dump dummy namespace from pre-7.3 source */ *************** *** 5486,5492 **** dumpType(Archive *fout, TypeInfo *tinfo) { /* Skip if not to be dumped */ ! if (!tinfo->dobj.dump || dataOnly) return; /* Dump out in proper style */ --- 5525,5531 ---- dumpType(Archive *fout, TypeInfo *tinfo) { /* Skip if not to be dumped */ ! if (!tinfo->dobj.dump || !WANT_PRE_SCHEMA(dumpObjFlags)) return; /* Dump out in proper style */ *************** *** 6131,6137 **** PQExpBuffer q; /* Skip if not to be dumped */ ! if (!stinfo->dobj.dump || dataOnly) return; q = createPQExpBuffer(); --- 6170,6176 ---- PQExpBuffer q; /* Skip if not to be dumped */ ! if (!stinfo->dobj.dump || !WANT_PRE_SCHEMA(dumpObjFlags)) return; q = createPQExpBuffer(); *************** *** 6178,6184 **** if (!include_everything) return false; /* And they're schema not data */ ! if (dataOnly) return false; return true; } --- 6217,6223 ---- if (!include_everything) return false; /* And they're schema not data */ ! if (!WANT_PRE_SCHEMA(dumpObjFlags)) return false; return true; } *************** *** 6199,6205 **** FuncInfo *funcInfo; FuncInfo *validatorInfo = NULL; ! if (dataOnly) return; /* --- 6238,6244 ---- FuncInfo *funcInfo; FuncInfo *validatorInfo = NULL; ! if (!WANT_PRE_SCHEMA(dumpObjFlags)) return; /* *************** *** 6439,6445 **** int i; /* Skip if not to be dumped */ ! if (!finfo->dobj.dump || dataOnly) return; query = createPQExpBuffer(); --- 6478,6484 ---- int i; /* Skip if not to be dumped */ ! if (!finfo->dobj.dump || !WANT_PRE_SCHEMA(dumpObjFlags)) return; query = createPQExpBuffer(); *************** *** 6800,6806 **** TypeInfo *sourceInfo; TypeInfo *targetInfo; ! if (dataOnly) return; if (OidIsValid(cast->castfunc)) --- 6839,6845 ---- TypeInfo *sourceInfo; TypeInfo *targetInfo; ! if (!WANT_PRE_SCHEMA(dumpObjFlags)) return; if (OidIsValid(cast->castfunc)) *************** *** 6950,6956 **** char *oprcanhash; /* Skip if not to be dumped */ ! if (!oprinfo->dobj.dump || dataOnly) return; /* --- 6989,6995 ---- char *oprcanhash; /* Skip if not to be dumped */ ! if (!oprinfo->dobj.dump || !WANT_PRE_SCHEMA(dumpObjFlags)) return; /* *************** *** 7334,7340 **** int i; /* Skip if not to be dumped */ ! if (!opcinfo->dobj.dump || dataOnly) return; /* --- 7373,7379 ---- int i; /* Skip if not to be dumped */ ! if (!opcinfo->dobj.dump || !WANT_PRE_SCHEMA(dumpObjFlags)) return; /* *************** *** 7622,7628 **** int i; /* Skip if not to be dumped */ ! if (!opfinfo->dobj.dump || dataOnly) return; /* --- 7661,7667 ---- int i; /* Skip if not to be dumped */ ! if (!opfinfo->dobj.dump || !WANT_PRE_SCHEMA(dumpObjFlags)) return; /* *************** *** 7871,7877 **** bool condefault; /* Skip if not to be dumped */ ! if (!convinfo->dobj.dump || dataOnly) return; query = createPQExpBuffer(); --- 7910,7916 ---- bool condefault; /* Skip if not to be dumped */ ! if (!convinfo->dobj.dump || !WANT_PRE_SCHEMA(dumpObjFlags)) return; query = createPQExpBuffer(); *************** *** 8025,8031 **** bool convertok; /* Skip if not to be dumped */ ! if (!agginfo->aggfn.dobj.dump || dataOnly) return; query = createPQExpBuffer(); --- 8064,8070 ---- bool convertok; /* Skip if not to be dumped */ ! if (!agginfo->aggfn.dobj.dump || !WANT_PRE_SCHEMA(dumpObjFlags)) return; query = createPQExpBuffer(); *************** *** 8228,8234 **** PQExpBuffer delq; /* Skip if not to be dumped */ ! if (!prsinfo->dobj.dump || dataOnly) return; q = createPQExpBuffer(); --- 8267,8273 ---- PQExpBuffer delq; /* Skip if not to be dumped */ ! if (!prsinfo->dobj.dump || !WANT_PRE_SCHEMA(dumpObjFlags)) return; q = createPQExpBuffer(); *************** *** 8297,8303 **** char *tmplname; /* Skip if not to be dumped */ ! if (!dictinfo->dobj.dump || dataOnly) return; q = createPQExpBuffer(); --- 8336,8342 ---- char *tmplname; /* Skip if not to be dumped */ ! if (!dictinfo->dobj.dump || !WANT_PRE_SCHEMA(dumpObjFlags)) return; q = createPQExpBuffer(); *************** *** 8382,8388 **** PQExpBuffer delq; /* Skip if not to be dumped */ ! if (!tmplinfo->dobj.dump || dataOnly) return; q = createPQExpBuffer(); --- 8421,8427 ---- PQExpBuffer delq; /* Skip if not to be dumped */ ! if (!tmplinfo->dobj.dump || !WANT_PRE_SCHEMA(dumpObjFlags)) return; q = createPQExpBuffer(); *************** *** 8448,8454 **** int i_dictname; /* Skip if not to be dumped */ ! if (!cfginfo->dobj.dump || dataOnly) return; q = createPQExpBuffer(); --- 8487,8493 ---- int i_dictname; /* Skip if not to be dumped */ ! if (!cfginfo->dobj.dump || !WANT_PRE_SCHEMA(dumpObjFlags)) return; q = createPQExpBuffer(); *************** *** 8584,8590 **** PQExpBuffer sql; /* Do nothing if ACL dump is not enabled */ ! if (dataOnly || aclsSkip) return; sql = createPQExpBuffer(); --- 8623,8629 ---- PQExpBuffer sql; /* Do nothing if ACL dump is not enabled */ ! if (!WANT_PRE_SCHEMA(dumpObjFlags) || aclsSkip) return; sql = createPQExpBuffer(); *************** *** 8621,8627 **** { if (tbinfo->relkind == RELKIND_SEQUENCE) dumpSequence(fout, tbinfo); ! else if (!dataOnly) dumpTableSchema(fout, tbinfo); /* Handle the ACL here */ --- 8660,8666 ---- { if (tbinfo->relkind == RELKIND_SEQUENCE) dumpSequence(fout, tbinfo); ! else if (WANT_PRE_SCHEMA(dumpObjFlags)) dumpTableSchema(fout, tbinfo); /* Handle the ACL here */ *************** *** 8928,8934 **** PQExpBuffer delq; /* Only print it if "separate" mode is selected */ ! if (!tbinfo->dobj.dump || !adinfo->separate || dataOnly) return; /* Don't print inherited defaults, either */ --- 8967,8973 ---- PQExpBuffer delq; /* Only print it if "separate" mode is selected */ ! if (!tbinfo->dobj.dump || !adinfo->separate || !WANT_PRE_SCHEMA(dumpObjFlags)) return; /* Don't print inherited defaults, either */ *************** *** 9013,9019 **** PQExpBuffer q; PQExpBuffer delq; ! if (dataOnly) return; q = createPQExpBuffer(); --- 9052,9058 ---- PQExpBuffer q; PQExpBuffer delq; ! if (!WANT_POST_SCHEMA(dumpObjFlags)) return; q = createPQExpBuffer(); *************** *** 9082,9088 **** PQExpBuffer delq; /* Skip if not to be dumped */ ! if (!coninfo->dobj.dump || dataOnly) return; q = createPQExpBuffer(); --- 9121,9127 ---- PQExpBuffer delq; /* Skip if not to be dumped */ ! if (!coninfo->dobj.dump || !WANT_POST_SCHEMA(dumpObjFlags)) return; q = createPQExpBuffer(); *************** *** 9452,9458 **** * * Add a 'SETVAL(seq, last_val, iscalled)' as part of a "data" dump. */ ! if (!dataOnly) { resetPQExpBuffer(delqry); --- 9491,9497 ---- * * Add a 'SETVAL(seq, last_val, iscalled)' as part of a "data" dump. */ ! if (WANT_PRE_SCHEMA(dumpObjFlags)) { resetPQExpBuffer(delqry); *************** *** 9545,9551 **** tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); } ! if (!schemaOnly) { resetPQExpBuffer(query); appendPQExpBuffer(query, "SELECT pg_catalog.setval("); --- 9584,9590 ---- tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); } ! if (WANT_PRE_SCHEMA(dumpObjFlags)) { resetPQExpBuffer(query); appendPQExpBuffer(query, "SELECT pg_catalog.setval("); *************** *** 9578,9584 **** const char *p; int findx; ! if (dataOnly) return; query = createPQExpBuffer(); --- 9617,9623 ---- const char *p; int findx; ! if (!WANT_POST_SCHEMA(dumpObjFlags)) return; query = createPQExpBuffer(); *************** *** 9779,9785 **** PGresult *res; /* Skip if not to be dumped */ ! if (!rinfo->dobj.dump || dataOnly) return; /* --- 9818,9824 ---- PGresult *res; /* Skip if not to be dumped */ ! if (!rinfo->dobj.dump || !WANT_POST_SCHEMA(dumpObjFlags)) return; /* Index: src/bin/pg_dump/pg_restore.c =================================================================== RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/bin/pg_dump/pg_restore.c,v retrieving revision 1.85 diff -c -r1.85 pg_restore.c *** src/bin/pg_dump/pg_restore.c 11 Dec 2007 19:01:06 -0000 1.85 --- src/bin/pg_dump/pg_restore.c 20 Mar 2008 11:48:34 -0000 *************** *** 77,82 **** --- 77,91 ---- static int use_setsessauth = 0; static int disable_triggers = 0; static int no_data_for_failed_tables = 0; + bool dataOnly = false; + bool schemaOnly = false; + + static int use_schemaPreLoadOnly; + static int use_schemaPostLoadOnly; + int num_object_groups = 0; + + int dumpObjFlags; + struct option cmdopts[] = { {"clean", 0, NULL, 'c'}, *************** *** 113,118 **** --- 122,129 ---- {"use-set-session-authorization", no_argument, &use_setsessauth, 1}, {"disable-triggers", no_argument, &disable_triggers, 1}, {"no-data-for-failed-tables", no_argument, &no_data_for_failed_tables, 1}, + {"schema-pre-load", no_argument, &use_schemaPreLoadOnly, 1}, + {"schema-post-load", no_argument, &use_schemaPostLoadOnly, 1}, {NULL, 0, NULL, 0} }; *************** *** 143,149 **** switch (c) { case 'a': /* Dump data only */ ! opts->dataOnly = 1; break; case 'c': /* clean (i.e., drop) schema prior to create */ opts->dropSchema = 1; --- 154,160 ---- switch (c) { case 'a': /* Dump data only */ ! dataOnly = true; break; case 'c': /* clean (i.e., drop) schema prior to create */ opts->dropSchema = 1; *************** *** 211,217 **** opts->triggerNames = strdup(optarg); break; case 's': /* dump schema only */ ! opts->schemaOnly = 1; break; case 'S': /* Superuser username */ if (strlen(optarg) != 0) --- 222,228 ---- opts->triggerNames = strdup(optarg); break; case 's': /* dump schema only */ ! schemaOnly = true; break; case 'S': /* Superuser username */ if (strlen(optarg) != 0) *************** *** 289,294 **** --- 300,340 ---- opts->useDB = 1; } + /* + * Look for conflicting options relating to object types + */ + if (dataOnly) + num_object_groups++; + if (schemaOnly) + num_object_groups++; + if (use_schemaPreLoadOnly == 1) + num_object_groups++; + if (use_schemaPostLoadOnly == 1) + num_object_groups++; + + if (num_object_groups > 1) + { + write_msg(NULL, "multiple object groups cannot be used together\n"); + exit(1); + } + + /* + * Decide which of the object groups we will dump + */ + dumpObjFlags = REQ_ALL; + + if (dataOnly) + dumpObjFlags = REQ_DATA; + + if (use_schemaPreLoadOnly == 1) + dumpObjFlags = REQ_PRE_SCHEMA; + + if (use_schemaPostLoadOnly == 1) + dumpObjFlags = REQ_POST_SCHEMA; + + if (schemaOnly) + dumpObjFlags = (REQ_PRE_SCHEMA | REQ_POST_SCHEMA); + opts->disable_triggers = disable_triggers; opts->use_setsessauth = use_setsessauth; opts->noDataForFailedTables = no_data_for_failed_tables;
-- Sent via pgsql-patches mailing list (pgsql-patches@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-patches