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

Reply via email to