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, &quote_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

Reply via email to