Mark Dilger <hornschnor...@gmail.com> writes:
> I use CREATE RULE within startup files in the fork that I maintain.  I have
> lots of them, totaling perhaps 50k lines of rule code.  I don't think any of 
> that
> code would have a problem with the double-newline separation you propose,
> which seems a more elegant solution to me.  Admittedly, the double-newline
> separation would need to be documented at the top of each sql file, otherwise
> it would be quite surprising to those unfamiliar with it.

> You mentioned upthread that introducing a syntax error in one of these files
> results in a not-so-helpful error message that dumps the contents of the
> entire file.  I can confirm that happens, and is hardly useful.

Not having heard any ideas that sounded better than semi-newline-newline,
I went ahead and finished up this patch on that basis.  Attached are two
patch files; the first one redefines the behavior of -j, and the second
one modifies initdb to use only one standalone-backend run.  I present
them this way to emphasize that the -j change doesn't break much of
anything: initdb still works if you apply only the first patch.  And
I didn't change anything in the initdb input files, except for adding
the comment documentation Mark suggests above.

In passing in the first patch, I got rid of the TCOP_DONTUSENEWLINE
#define, which could not have been used by anyone in a very long time
because it would break initdb.  I then realized that
src/include/tcop/tcopdebug.h is completely dead code, because the
other debugging symbol it claims to specify got ripped out long ago.
And to add insult to injury, that file is included noplace.  I imagine
Bruce's pgrminclude tool got rid of the inclusion that must once have
existed in postgres.c, after observing that postgres.c still compiled
without it :-(.  (That tool really requires more adult supervision
than it has gotten.) So anyway, this patch removes tcopdebug.h entirely.

The second patch consists of removing extra backend starts/stops
and converting all of initdb's code to run in -j mode, rather than the
mishmash of -j and not-j behavior that was there before.  I changed
all the semicolon-newlines in initdb's command strings to
semicolon-newline-newlines.  As mentioned before, only a small number of
those changes *had* to be made to get it to work, namely the ones around
VACUUM and CREATE DATABASE statements, but I felt that for consistency
and error localization all of them should be changed.  I also failed to
resist the temptation to const-ify some of the arrays more thoroughly.

Barring objections I'll push this into HEAD soon.

                        regards, tom lane

diff --git a/doc/src/sgml/ref/postgres-ref.sgml b/doc/src/sgml/ref/postgres-ref.sgml
index e2e9909..d60d4ff 100644
*** a/doc/src/sgml/ref/postgres-ref.sgml
--- b/doc/src/sgml/ref/postgres-ref.sgml
*************** PostgreSQL documentation
*** 529,535 ****
      </indexterm>
  
      <para>
!      The following options only apply to the single-user mode.
      </para>
  
      <variablelist>
--- 529,537 ----
      </indexterm>
  
      <para>
!      The following options only apply to the single-user mode
!      (see <xref linkend="app-postgres-single-user"
!      endterm="app-postgres-single-user-title">).
      </para>
  
      <variablelist>
*************** PostgreSQL documentation
*** 558,564 ****
        <term><option>-E</option></term>
        <listitem>
         <para>
!         Echo all commands.
         </para>
        </listitem>
       </varlistentry>
--- 560,566 ----
        <term><option>-E</option></term>
        <listitem>
         <para>
!         Echo all commands to standard output before executing them.
         </para>
        </listitem>
       </varlistentry>
*************** PostgreSQL documentation
*** 567,573 ****
        <term><option>-j</option></term>
        <listitem>
         <para>
!         Disables use of newline as a statement delimiter.
         </para>
        </listitem>
       </varlistentry>
--- 569,576 ----
        <term><option>-j</option></term>
        <listitem>
         <para>
!         Use semicolon followed by two newlines, rather than just newline,
!         as the command entry terminator.
         </para>
        </listitem>
       </varlistentry>
*************** PostgreSQL documentation
*** 760,767 ****
    </para>
   </refsect1>
  
!  <refsect1>
!   <title>Usage</title>
  
     <para>
      To start a single-user mode server, use a command like
--- 763,770 ----
    </para>
   </refsect1>
  
!  <refsect1 id="app-postgres-single-user">
!   <title id="app-postgres-single-user-title">Single-User Mode</title>
  
     <para>
      To start a single-user mode server, use a command like
*************** PostgreSQL documentation
*** 778,807 ****
      entry terminator; there is no intelligence about semicolons,
      as there is in <application>psql</>.  To continue a command
      across multiple lines, you must type backslash just before each
!     newline except the last one.
     </para>
  
     <para>
!     But if you use the <option>-j</> command line switch, then newline does
!     not terminate command entry.  In this case, the server will read the standard input
!     until the end-of-file (<acronym>EOF</>) marker, then
!     process the input as a single command string.  Backslash-newline is not
!     treated specially in this case.
     </para>
  
     <para>
      To quit the session, type <acronym>EOF</acronym>
      (<keycombo action="simul"><keycap>Control</><keycap>D</></>, usually).
!     If you've
!     used <option>-j</>, two consecutive <acronym>EOF</>s are needed to exit.
     </para>
  
     <para>
      Note that the single-user mode server does not provide sophisticated
      line-editing features (no command history, for example).
!     Single-User mode also does not do any background processing, like
!     automatic checkpoints.
! 
     </para>
   </refsect1>
  
--- 781,820 ----
      entry terminator; there is no intelligence about semicolons,
      as there is in <application>psql</>.  To continue a command
      across multiple lines, you must type backslash just before each
!     newline except the last one.  The backslash and adjacent newline are
!     both dropped from the input command.  Note that this will happen even
!     when within a string literal or comment.
     </para>
  
     <para>
!     But if you use the <option>-j</> command line switch, a single newline
!     does not terminate command entry; instead, the sequence
!     semicolon-newline-newline does.  That is, type a semicolon immediately
!     followed by a completely empty line.  Backslash-newline is not
!     treated specially in this mode.  Again, there is no intelligence about
!     such a sequence appearing within a string literal or comment.
!    </para>
! 
!    <para>
!     In either input mode, if you type a semicolon that is not just before or
!     part of a command entry terminator, it is considered a command separator.
!     When you do type a command entry terminator, the multiple statements
!     you've entered will be executed as a single transaction.
     </para>
  
     <para>
      To quit the session, type <acronym>EOF</acronym>
      (<keycombo action="simul"><keycap>Control</><keycap>D</></>, usually).
!     If you've entered any text since the last command entry terminator,
!     then <acronym>EOF</acronym> will be taken as a command entry terminator,
!     and another <acronym>EOF</> will be needed to exit.
     </para>
  
     <para>
      Note that the single-user mode server does not provide sophisticated
      line-editing features (no command history, for example).
!     Single-user mode also does not do any background processing, such as
!     automatic checkpoints or replication.
     </para>
   </refsect1>
  
diff --git a/src/backend/catalog/information_schema.sql b/src/backend/catalog/information_schema.sql
index 6e1b241..2239859 100644
*** a/src/backend/catalog/information_schema.sql
--- b/src/backend/catalog/information_schema.sql
***************
*** 5,10 ****
--- 5,18 ----
   * Copyright (c) 2003-2015, PostgreSQL Global Development Group
   *
   * src/backend/catalog/information_schema.sql
+  *
+  * Note: this file is read in single-user -j mode, which means that the
+  * command terminator is semicolon-newline-newline; whenever the backend
+  * sees that, it stops and executes what it's got.  If you write a lot of
+  * statements without empty lines between, they'll all get quoted to you
+  * in any error message about one of them, so don't do that.  Also, you
+  * cannot write a semicolon immediately followed by an empty line in a
+  * string literal (including a function body!) or a multiline comment.
   */
  
  /*
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index ccc030f..536c805 100644
*** a/src/backend/catalog/system_views.sql
--- b/src/backend/catalog/system_views.sql
***************
*** 4,9 ****
--- 4,17 ----
   * Copyright (c) 1996-2015, PostgreSQL Global Development Group
   *
   * src/backend/catalog/system_views.sql
+  *
+  * Note: this file is read in single-user -j mode, which means that the
+  * command terminator is semicolon-newline-newline; whenever the backend
+  * sees that, it stops and executes what it's got.  If you write a lot of
+  * statements without empty lines between, they'll all get quoted to you
+  * in any error message about one of them, so don't do that.  Also, you
+  * cannot write a semicolon immediately followed by an empty line in a
+  * string literal (including a function body!) or a multiline comment.
   */
  
  CREATE VIEW pg_roles AS
diff --git a/src/backend/snowball/snowball.sql.in b/src/backend/snowball/snowball.sql.in
index 2f68393..68363f1 100644
*** a/src/backend/snowball/snowball.sql.in
--- b/src/backend/snowball/snowball.sql.in
***************
*** 1,6 ****
! -- src/backend/snowball/snowball.sql.in$
  
- -- text search configuration for _LANGNAME_ language
  CREATE TEXT SEARCH DICTIONARY _DICTNAME_
  	(TEMPLATE = snowball, Language = _LANGNAME_ _STOPWORDS_);
  
--- 1,22 ----
! /*
!  * text search configuration for _LANGNAME_ language
!  *
!  * Copyright (c) 2007-2015, PostgreSQL Global Development Group
!  *
!  * src/backend/snowball/snowball.sql.in
!  *
!  * _LANGNAME_ and certain other macros are replaced for each language;
!  * see the Makefile for details.
!  *
!  * Note: this file is read in single-user -j mode, which means that the
!  * command terminator is semicolon-newline-newline; whenever the backend
!  * sees that, it stops and executes what it's got.  If you write a lot of
!  * statements without empty lines between, they'll all get quoted to you
!  * in any error message about one of them, so don't do that.  Also, you
!  * cannot write a semicolon immediately followed by an empty line in a
!  * string literal (including a function body!) or a multiline comment.
!  */
  
  CREATE TEXT SEARCH DICTIONARY _DICTNAME_
  	(TEMPLATE = snowball, Language = _LANGNAME_ _STOPWORDS_);
  
diff --git a/src/backend/snowball/snowball_func.sql.in b/src/backend/snowball/snowball_func.sql.in
index e7d4510..debb0e0 100644
*** a/src/backend/snowball/snowball_func.sql.in
--- b/src/backend/snowball/snowball_func.sql.in
***************
*** 1,4 ****
! -- src/backend/snowball/snowball_func.sql.in$
  
  SET search_path = pg_catalog;
  
--- 1,21 ----
! /*
!  * Create underlying C functions for Snowball stemmers
!  *
!  * Copyright (c) 2007-2015, PostgreSQL Global Development Group
!  *
!  * src/backend/snowball/snowball_func.sql.in
!  *
!  * This file is combined with multiple instances of snowball.sql.in to
!  * build snowball_create.sql, which is executed during initdb.
!  *
!  * Note: this file is read in single-user -j mode, which means that the
!  * command terminator is semicolon-newline-newline; whenever the backend
!  * sees that, it stops and executes what it's got.  If you write a lot of
!  * statements without empty lines between, they'll all get quoted to you
!  * in any error message about one of them, so don't do that.  Also, you
!  * cannot write a semicolon immediately followed by an empty line in a
!  * string literal (including a function body!) or a multiline comment.
!  */
  
  SET search_path = pg_catalog;
  
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 1dc2eb0..4ae2548 100644
*** a/src/backend/tcop/postgres.c
--- b/src/backend/tcop/postgres.c
*************** static CachedPlanSource *unnamed_stmt_ps
*** 157,174 ****
  
  /* assorted command-line switches */
  static const char *userDoption = NULL;	/* -D switch */
- 
  static bool EchoQuery = false;	/* -E switch */
! 
! /*
!  * people who want to use EOF should #define DONTUSENEWLINE in
!  * tcop/tcopdebug.h
!  */
! #ifndef TCOP_DONTUSENEWLINE
! static int	UseNewLine = 1;		/* Use newlines query delimiters (the default) */
! #else
! static int	UseNewLine = 0;		/* Use EOF as query delimiters */
! #endif   /* TCOP_DONTUSENEWLINE */
  
  /* whether or not, and why, we were canceled by conflict with recovery */
  static bool RecoveryConflictPending = false;
--- 157,164 ----
  
  /* assorted command-line switches */
  static const char *userDoption = NULL;	/* -D switch */
  static bool EchoQuery = false;	/* -E switch */
! static bool UseSemiNewlineNewline = false;		/* -j switch */
  
  /* whether or not, and why, we were canceled by conflict with recovery */
  static bool RecoveryConflictPending = false;
*************** static int
*** 219,226 ****
  InteractiveBackend(StringInfo inBuf)
  {
  	int			c;				/* character read from getc() */
- 	bool		end = false;	/* end-of-input flag */
- 	bool		backslashSeen = false;	/* have we seen a \ ? */
  
  	/*
  	 * display a prompt and obtain input from the user
--- 209,214 ----
*************** InteractiveBackend(StringInfo inBuf)
*** 230,284 ****
  
  	resetStringInfo(inBuf);
  
! 	if (UseNewLine)
  	{
! 		/*
! 		 * if we are using \n as a delimiter, then read characters until the
! 		 * \n.
! 		 */
! 		while ((c = interactive_getc()) != EOF)
  		{
! 			if (c == '\n')
  			{
! 				if (backslashSeen)
  				{
  					/* discard backslash from inBuf */
  					inBuf->data[--inBuf->len] = '\0';
! 					backslashSeen = false;
  					continue;
  				}
  				else
  				{
! 					/* keep the newline character */
  					appendStringInfoChar(inBuf, '\n');
  					break;
  				}
  			}
- 			else if (c == '\\')
- 				backslashSeen = true;
- 			else
- 				backslashSeen = false;
- 
- 			appendStringInfoChar(inBuf, (char) c);
  		}
  
! 		if (c == EOF)
! 			end = true;
! 	}
! 	else
! 	{
! 		/*
! 		 * otherwise read characters until EOF.
! 		 */
! 		while ((c = interactive_getc()) != EOF)
! 			appendStringInfoChar(inBuf, (char) c);
! 
! 		/* No input before EOF signal means time to quit. */
! 		if (inBuf->len == 0)
! 			end = true;
  	}
  
! 	if (end)
  		return EOF;
  
  	/*
--- 218,273 ----
  
  	resetStringInfo(inBuf);
  
! 	/*
! 	 * Read characters until EOF or the appropriate delimiter is seen.
! 	 */
! 	while ((c = interactive_getc()) != EOF)
  	{
! 		if (c == '\n')
  		{
! 			if (UseSemiNewlineNewline)
  			{
! 				/*
! 				 * In -j mode, semicolon followed by two newlines ends the
! 				 * command; otherwise treat newline as regular character.
! 				 */
! 				if (inBuf->len > 1 &&
! 					inBuf->data[inBuf->len - 1] == '\n' &&
! 					inBuf->data[inBuf->len - 2] == ';')
! 				{
! 					/* might as well drop the second newline */
! 					break;
! 				}
! 			}
! 			else
! 			{
! 				/*
! 				 * In plain mode, newline ends the command unless preceded by
! 				 * backslash.
! 				 */
! 				if (inBuf->len > 0 &&
! 					inBuf->data[inBuf->len - 1] == '\\')
  				{
  					/* discard backslash from inBuf */
  					inBuf->data[--inBuf->len] = '\0';
! 					/* discard newline too */
  					continue;
  				}
  				else
  				{
! 					/* keep the newline character, but end the command */
  					appendStringInfoChar(inBuf, '\n');
  					break;
  				}
  			}
  		}
  
! 		/* Not newline, or newline treated as regular character */
! 		appendStringInfoChar(inBuf, (char) c);
  	}
  
! 	/* No input before EOF signal means time to quit. */
! 	if (c == EOF && inBuf->len == 0)
  		return EOF;
  
  	/*
*************** process_postgres_switches(int argc, char
*** 3391,3397 ****
  
  			case 'j':
  				if (secure)
! 					UseNewLine = 0;
  				break;
  
  			case 'k':
--- 3380,3386 ----
  
  			case 'j':
  				if (secure)
! 					UseSemiNewlineNewline = true;
  				break;
  
  			case 'k':
diff --git a/src/include/tcop/tcopdebug.h b/src/include/tcop/tcopdebug.h
index d7145ce..e69de29 100644
*** a/src/include/tcop/tcopdebug.h
--- b/src/include/tcop/tcopdebug.h
***************
*** 1,44 ****
- /*-------------------------------------------------------------------------
-  *
-  * tcopdebug.h
-  *	  #defines governing debugging behaviour in the traffic cop
-  *
-  *
-  * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
-  * Portions Copyright (c) 1994, Regents of the University of California
-  *
-  * src/include/tcop/tcopdebug.h
-  *
-  *-------------------------------------------------------------------------
-  */
- #ifndef TCOPDEBUG_H
- #define TCOPDEBUG_H
- 
- /* ----------------------------------------------------------------
-  *		debugging defines.
-  *
-  *		If you want certain debugging behaviour, then #define
-  *		the variable to 1, else #undef it. -cim 10/26/89
-  * ----------------------------------------------------------------
-  */
- 
- /* ----------------
-  *		TCOP_SHOWSTATS controls whether or not buffer and
-  *		access method statistics are shown for each query.  -cim 2/9/89
-  * ----------------
-  */
- #undef TCOP_SHOWSTATS
- 
- /* ----------------
-  *		TCOP_DONTUSENEWLINE controls the default setting of
-  *		the UseNewLine variable in postgres.c
-  * ----------------
-  */
- #undef TCOP_DONTUSENEWLINE
- 
- /* ----------------------------------------------------------------
-  *		#defines controlled by above definitions
-  * ----------------------------------------------------------------
-  */
- 
- #endif   /* TCOPDEBUG_H */
--- 0 ----
diff --git a/src/backend/utils/mb/conversion_procs/Makefile b/src/backend/utils/mb/conversion_procs/Makefile
index 8481721..cad5948 100644
*** a/src/backend/utils/mb/conversion_procs/Makefile
--- b/src/backend/utils/mb/conversion_procs/Makefile
*************** $(SQLSCRIPT): Makefile
*** 181,186 ****
--- 181,187 ----
  		echo "DROP CONVERSION pg_catalog.$$name;"; \
  		echo "CREATE DEFAULT CONVERSION pg_catalog.$$name FOR '$$se' TO '$$de' FROM $$func;"; \
  	        echo "COMMENT ON CONVERSION pg_catalog.$$name IS 'conversion for $$se to $$de';"; \
+ 		echo; \
  	done > $@
  
  $(REGRESSION_SCRIPT): Makefile
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index feeff9e..31b2588 100644
*** a/src/bin/initdb/initdb.c
--- b/src/bin/initdb/initdb.c
***************
*** 79,85 ****
  /* Ideally this would be in a .h file, but it hardly seems worth the trouble */
  extern const char *select_default_timezone(const char *share_path);
  
! static const char *auth_methods_host[] = {"trust", "reject", "md5", "password", "ident", "radius",
  #ifdef ENABLE_GSS
  	"gss",
  #endif
--- 79,86 ----
  /* Ideally this would be in a .h file, but it hardly seems worth the trouble */
  extern const char *select_default_timezone(const char *share_path);
  
! static const char *const auth_methods_host[] = {
! 	"trust", "reject", "md5", "password", "ident", "radius",
  #ifdef ENABLE_GSS
  	"gss",
  #endif
*************** static const char *auth_methods_host[] =
*** 95,109 ****
  #ifdef USE_SSL
  	"cert",
  #endif
! NULL};
! static const char *auth_methods_local[] = {"trust", "reject", "md5", "password", "peer", "radius",
  #ifdef USE_PAM
  	"pam", "pam ",
  #endif
  #ifdef USE_LDAP
  	"ldap",
  #endif
! NULL};
  
  /*
   * these values are passed in by makefile defines
--- 96,113 ----
  #ifdef USE_SSL
  	"cert",
  #endif
! 	NULL
! };
! static const char *const auth_methods_local[] = {
! 	"trust", "reject", "md5", "password", "peer", "radius",
  #ifdef USE_PAM
  	"pam", "pam ",
  #endif
  #ifdef USE_LDAP
  	"ldap",
  #endif
! 	NULL
! };
  
  /*
   * these values are passed in by makefile defines
*************** static char *authwarning = NULL;
*** 185,193 ****
   * (no quoting to worry about).
   */
  static const char *boot_options = "-F";
! static const char *backend_options = "--single -F -O -c search_path=pg_catalog -c exit_on_error=true";
  
! static const char *subdirs[] = {
  	"global",
  	"pg_xlog",
  	"pg_xlog/archive_status",
--- 189,197 ----
   * (no quoting to worry about).
   */
  static const char *boot_options = "-F";
! static const char *backend_options = "--single -F -O -j -c search_path=pg_catalog -c exit_on_error=true";
  
! static const char *const subdirs[] = {
  	"global",
  	"pg_xlog",
  	"pg_xlog/archive_status",
*************** static void set_null_conf(void);
*** 244,264 ****
  static void test_config_settings(void);
  static void setup_config(void);
  static void bootstrap_template1(void);
! static void setup_auth(void);
! static void get_set_pwd(void);
! static void setup_depend(void);
! static void setup_sysviews(void);
! static void setup_description(void);
! static void setup_collation(void);
! static void setup_conversion(void);
! static void setup_dictionary(void);
! static void setup_privileges(void);
  static void set_info_version(void);
! static void setup_schema(void);
! static void load_plpgsql(void);
! static void vacuum_db(void);
! static void make_template0(void);
! static void make_postgres(void);
  static void fsync_pgdata(void);
  static void trapsig(int signum);
  static void check_ok(void);
--- 248,268 ----
  static void test_config_settings(void);
  static void setup_config(void);
  static void bootstrap_template1(void);
! static void setup_auth(FILE *cmdfd);
! static void get_set_pwd(FILE *cmdfd);
! static void setup_depend(FILE *cmdfd);
! static void setup_sysviews(FILE *cmdfd);
! static void setup_description(FILE *cmdfd);
! static void setup_collation(FILE *cmdfd);
! static void setup_conversion(FILE *cmdfd);
! static void setup_dictionary(FILE *cmdfd);
! static void setup_privileges(FILE *cmdfd);
  static void set_info_version(void);
! static void setup_schema(FILE *cmdfd);
! static void load_plpgsql(FILE *cmdfd);
! static void vacuum_db(FILE *cmdfd);
! static void make_template0(FILE *cmdfd);
! static void make_postgres(FILE *cmdfd);
  static void fsync_pgdata(void);
  static void trapsig(int signum);
  static void check_ok(void);
*************** bootstrap_template1(void)
*** 1545,1589 ****
   * set up the shadow password table
   */
  static void
! setup_auth(void)
  {
! 	PG_CMD_DECL;
! 	const char **line;
! 	static const char *pg_authid_setup[] = {
  		/*
  		 * The authid table shouldn't be readable except through views, to
  		 * ensure passwords are not publicly visible.
  		 */
! 		"REVOKE ALL on pg_authid FROM public;\n",
  		NULL
  	};
  
- 	fputs(_("initializing pg_authid ... "), stdout);
- 	fflush(stdout);
- 
- 	snprintf(cmd, sizeof(cmd),
- 			 "\"%s\" %s template1 >%s",
- 			 backend_exec, backend_options,
- 			 DEVNULL);
- 
- 	PG_CMD_OPEN;
- 
  	for (line = pg_authid_setup; *line != NULL; line++)
  		PG_CMD_PUTS(*line);
- 
- 	PG_CMD_CLOSE;
- 
- 	check_ok();
  }
  
  /*
   * get the superuser password if required, and call postgres to set it
   */
  static void
! get_set_pwd(void)
  {
- 	PG_CMD_DECL;
- 
  	char	   *pwd1,
  			   *pwd2;
  
--- 1549,1576 ----
   * set up the shadow password table
   */
  static void
! setup_auth(FILE *cmdfd)
  {
! 	const char *const * line;
! 	static const char *const pg_authid_setup[] = {
  		/*
  		 * The authid table shouldn't be readable except through views, to
  		 * ensure passwords are not publicly visible.
  		 */
! 		"REVOKE ALL on pg_authid FROM public;\n\n",
  		NULL
  	};
  
  	for (line = pg_authid_setup; *line != NULL; line++)
  		PG_CMD_PUTS(*line);
  }
  
  /*
   * get the superuser password if required, and call postgres to set it
   */
  static void
! get_set_pwd(FILE *cmdfd)
  {
  	char	   *pwd1,
  			   *pwd2;
  
*************** get_set_pwd(void)
*** 1640,1675 ****
  		pwd1 = pg_strdup(pwdbuf);
  
  	}
- 	printf(_("setting password ... "));
- 	fflush(stdout);
  
! 	snprintf(cmd, sizeof(cmd),
! 			 "\"%s\" %s template1 >%s",
! 			 backend_exec, backend_options,
! 			 DEVNULL);
! 
! 	PG_CMD_OPEN;
! 
! 	PG_CMD_PRINTF2("ALTER USER \"%s\" WITH PASSWORD E'%s';\n",
  				   username, escape_quotes(pwd1));
  
- 	/* MM: pwd1 is no longer needed, freeing it */
  	free(pwd1);
- 
- 	PG_CMD_CLOSE;
- 
- 	check_ok();
  }
  
  /*
   * set up pg_depend
   */
  static void
! setup_depend(void)
  {
! 	PG_CMD_DECL;
! 	const char **line;
! 	static const char *pg_depend_setup[] = {
  		/*
  		 * Make PIN entries in pg_depend for all objects made so far in the
  		 * tables that the dependency code handles.  This is overkill (the
--- 1627,1647 ----
  		pwd1 = pg_strdup(pwdbuf);
  
  	}
  
! 	PG_CMD_PRINTF2("ALTER USER \"%s\" WITH PASSWORD E'%s';\n\n",
  				   username, escape_quotes(pwd1));
  
  	free(pwd1);
  }
  
  /*
   * set up pg_depend
   */
  static void
! setup_depend(FILE *cmdfd)
  {
! 	const char *const * line;
! 	static const char *const pg_depend_setup[] = {
  		/*
  		 * Make PIN entries in pg_depend for all objects made so far in the
  		 * tables that the dependency code handles.  This is overkill (the
*************** setup_depend(void)
*** 1684,1845 ****
  		 * First delete any already-made entries; PINs override all else, and
  		 * must be the only entries for their objects.
  		 */
! 		"DELETE FROM pg_depend;\n",
! 		"VACUUM pg_depend;\n",
! 		"DELETE FROM pg_shdepend;\n",
! 		"VACUUM pg_shdepend;\n",
  
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_class;\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_proc;\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_type;\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_cast;\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_constraint;\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_attrdef;\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_language;\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_operator;\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_opclass;\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_opfamily;\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_amop;\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_amproc;\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_rewrite;\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_trigger;\n",
  
  		/*
  		 * restriction here to avoid pinning the public namespace
  		 */
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
  		" FROM pg_namespace "
! 		"    WHERE nspname LIKE 'pg%';\n",
  
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_ts_parser;\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_ts_dict;\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_ts_template;\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_ts_config;\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_collation;\n",
  		"INSERT INTO pg_shdepend SELECT 0,0,0,0, tableoid,oid, 'p' "
! 		" FROM pg_authid;\n",
  		NULL
  	};
  
- 	fputs(_("initializing dependencies ... "), stdout);
- 	fflush(stdout);
- 
- 	snprintf(cmd, sizeof(cmd),
- 			 "\"%s\" %s template1 >%s",
- 			 backend_exec, backend_options,
- 			 DEVNULL);
- 
- 	PG_CMD_OPEN;
- 
  	for (line = pg_depend_setup; *line != NULL; line++)
  		PG_CMD_PUTS(*line);
- 
- 	PG_CMD_CLOSE;
- 
- 	check_ok();
  }
  
  /*
   * set up system views
   */
  static void
! setup_sysviews(void)
  {
- 	PG_CMD_DECL;
  	char	  **line;
  	char	  **sysviews_setup;
  
- 	fputs(_("creating system views ... "), stdout);
- 	fflush(stdout);
- 
  	sysviews_setup = readfile(system_views_file);
  
- 	/*
- 	 * We use -j here to avoid backslashing stuff in system_views.sql
- 	 */
- 	snprintf(cmd, sizeof(cmd),
- 			 "\"%s\" %s -j template1 >%s",
- 			 backend_exec, backend_options,
- 			 DEVNULL);
- 
- 	PG_CMD_OPEN;
- 
  	for (line = sysviews_setup; *line != NULL; line++)
  	{
  		PG_CMD_PUTS(*line);
  		free(*line);
  	}
  
- 	PG_CMD_CLOSE;
- 
  	free(sysviews_setup);
- 
- 	check_ok();
  }
  
  /*
   * load description data
   */
  static void
! setup_description(void)
  {
- 	PG_CMD_DECL;
- 
- 	fputs(_("loading system objects' descriptions ... "), stdout);
- 	fflush(stdout);
- 
- 	snprintf(cmd, sizeof(cmd),
- 			 "\"%s\" %s template1 >%s",
- 			 backend_exec, backend_options,
- 			 DEVNULL);
- 
- 	PG_CMD_OPEN;
- 
  	PG_CMD_PUTS("CREATE TEMP TABLE tmp_pg_description ( "
  				"	objoid oid, "
  				"	classname name, "
  				"	objsubid int4, "
! 				"	description text) WITHOUT OIDS;\n");
  
! 	PG_CMD_PRINTF1("COPY tmp_pg_description FROM E'%s';\n",
  				   escape_quotes(desc_file));
  
  	PG_CMD_PUTS("INSERT INTO pg_description "
  				" SELECT t.objoid, c.oid, t.objsubid, t.description "
  				"  FROM tmp_pg_description t, pg_class c "
! 				"    WHERE c.relname = t.classname;\n");
  
  	PG_CMD_PUTS("CREATE TEMP TABLE tmp_pg_shdescription ( "
  				" objoid oid, "
  				" classname name, "
! 				" description text) WITHOUT OIDS;\n");
  
! 	PG_CMD_PRINTF1("COPY tmp_pg_shdescription FROM E'%s';\n",
  				   escape_quotes(shdesc_file));
  
  	PG_CMD_PUTS("INSERT INTO pg_shdescription "
  				" SELECT t.objoid, c.oid, t.description "
  				"  FROM tmp_pg_shdescription t, pg_class c "
! 				"   WHERE c.relname = t.classname;\n");
  
  	/* Create default descriptions for operator implementation functions */
  	PG_CMD_PUTS("WITH funcdescs AS ( "
--- 1656,1773 ----
  		 * First delete any already-made entries; PINs override all else, and
  		 * must be the only entries for their objects.
  		 */
! 		"DELETE FROM pg_depend;\n\n",
! 		"VACUUM pg_depend;\n\n",
! 		"DELETE FROM pg_shdepend;\n\n",
! 		"VACUUM pg_shdepend;\n\n",
  
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_class;\n\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_proc;\n\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_type;\n\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_cast;\n\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_constraint;\n\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_attrdef;\n\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_language;\n\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_operator;\n\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_opclass;\n\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_opfamily;\n\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_amop;\n\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_amproc;\n\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_rewrite;\n\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_trigger;\n\n",
  
  		/*
  		 * restriction here to avoid pinning the public namespace
  		 */
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
  		" FROM pg_namespace "
! 		"    WHERE nspname LIKE 'pg%';\n\n",
  
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_ts_parser;\n\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_ts_dict;\n\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_ts_template;\n\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_ts_config;\n\n",
  		"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
! 		" FROM pg_collation;\n\n",
  		"INSERT INTO pg_shdepend SELECT 0,0,0,0, tableoid,oid, 'p' "
! 		" FROM pg_authid;\n\n",
  		NULL
  	};
  
  	for (line = pg_depend_setup; *line != NULL; line++)
  		PG_CMD_PUTS(*line);
  }
  
  /*
   * set up system views
   */
  static void
! setup_sysviews(FILE *cmdfd)
  {
  	char	  **line;
  	char	  **sysviews_setup;
  
  	sysviews_setup = readfile(system_views_file);
  
  	for (line = sysviews_setup; *line != NULL; line++)
  	{
  		PG_CMD_PUTS(*line);
  		free(*line);
  	}
  
  	free(sysviews_setup);
  }
  
  /*
   * load description data
   */
  static void
! setup_description(FILE *cmdfd)
  {
  	PG_CMD_PUTS("CREATE TEMP TABLE tmp_pg_description ( "
  				"	objoid oid, "
  				"	classname name, "
  				"	objsubid int4, "
! 				"	description text) WITHOUT OIDS;\n\n");
  
! 	PG_CMD_PRINTF1("COPY tmp_pg_description FROM E'%s';\n\n",
  				   escape_quotes(desc_file));
  
  	PG_CMD_PUTS("INSERT INTO pg_description "
  				" SELECT t.objoid, c.oid, t.objsubid, t.description "
  				"  FROM tmp_pg_description t, pg_class c "
! 				"    WHERE c.relname = t.classname;\n\n");
  
  	PG_CMD_PUTS("CREATE TEMP TABLE tmp_pg_shdescription ( "
  				" objoid oid, "
  				" classname name, "
! 				" description text) WITHOUT OIDS;\n\n");
  
! 	PG_CMD_PRINTF1("COPY tmp_pg_shdescription FROM E'%s';\n\n",
  				   escape_quotes(shdesc_file));
  
  	PG_CMD_PUTS("INSERT INTO pg_shdescription "
  				" SELECT t.objoid, c.oid, t.description "
  				"  FROM tmp_pg_shdescription t, pg_class c "
! 				"   WHERE c.relname = t.classname;\n\n");
  
  	/* Create default descriptions for operator implementation functions */
  	PG_CMD_PUTS("WITH funcdescs AS ( "
*************** setup_description(void)
*** 1852,1862 ****
  				"  FROM funcdescs "
  				"  WHERE opdesc NOT LIKE 'deprecated%' AND "
  				"  NOT EXISTS (SELECT 1 FROM pg_description "
! 		  "    WHERE objoid = p_oid AND classoid = 'pg_proc'::regclass);\n");
! 
! 	PG_CMD_CLOSE;
! 
! 	check_ok();
  }
  
  #ifdef HAVE_LOCALE_T
--- 1780,1786 ----
  				"  FROM funcdescs "
  				"  WHERE opdesc NOT LIKE 'deprecated%' AND "
  				"  NOT EXISTS (SELECT 1 FROM pg_description "
! 		"    WHERE objoid = p_oid AND classoid = 'pg_proc'::regclass);\n\n");
  }
  
  #ifdef HAVE_LOCALE_T
*************** normalize_locale_name(char *new, const c
*** 1899,1905 ****
   * populate pg_collation
   */
  static void
! setup_collation(void)
  {
  #if defined(HAVE_LOCALE_T) && !defined(WIN32)
  	int			i;
--- 1823,1829 ----
   * populate pg_collation
   */
  static void
! setup_collation(FILE *cmdfd)
  {
  #if defined(HAVE_LOCALE_T) && !defined(WIN32)
  	int			i;
*************** setup_collation(void)
*** 1907,1934 ****
  	char		localebuf[NAMEDATALEN]; /* we assume ASCII so this is fine */
  	int			count = 0;
  
- 	PG_CMD_DECL;
- #endif
- 
- 	fputs(_("creating collations ... "), stdout);
- 	fflush(stdout);
- 
- #if defined(HAVE_LOCALE_T) && !defined(WIN32)
- 	snprintf(cmd, sizeof(cmd),
- 			 "\"%s\" %s template1 >%s",
- 			 backend_exec, backend_options,
- 			 DEVNULL);
- 
  	locale_a_handle = popen_check("locale -a", "r");
  	if (!locale_a_handle)
  		return;					/* complaint already printed */
  
- 	PG_CMD_OPEN;
- 
  	PG_CMD_PUTS("CREATE TEMP TABLE tmp_pg_collation ( "
  				"	collname name, "
  				"	locale name, "
! 				"	encoding int) WITHOUT OIDS;\n");
  
  	while (fgets(localebuf, sizeof(localebuf), locale_a_handle))
  	{
--- 1831,1844 ----
  	char		localebuf[NAMEDATALEN]; /* we assume ASCII so this is fine */
  	int			count = 0;
  
  	locale_a_handle = popen_check("locale -a", "r");
  	if (!locale_a_handle)
  		return;					/* complaint already printed */
  
  	PG_CMD_PUTS("CREATE TEMP TABLE tmp_pg_collation ( "
  				"	collname name, "
  				"	locale name, "
! 				"	encoding int) WITHOUT OIDS;\n\n");
  
  	while (fgets(localebuf, sizeof(localebuf), locale_a_handle))
  	{
*************** setup_collation(void)
*** 1988,1994 ****
  
  		quoted_locale = escape_quotes(localebuf);
  
! 		PG_CMD_PRINTF3("INSERT INTO tmp_pg_collation VALUES (E'%s', E'%s', %d);\n",
  					   quoted_locale, quoted_locale, enc);
  
  		/*
--- 1898,1904 ----
  
  		quoted_locale = escape_quotes(localebuf);
  
! 		PG_CMD_PRINTF3("INSERT INTO tmp_pg_collation VALUES (E'%s', E'%s', %d);\n\n",
  					   quoted_locale, quoted_locale, enc);
  
  		/*
*************** setup_collation(void)
*** 2000,2006 ****
  		{
  			char	   *quoted_alias = escape_quotes(alias);
  
! 			PG_CMD_PRINTF3("INSERT INTO tmp_pg_collation VALUES (E'%s', E'%s', %d);\n",
  						   quoted_alias, quoted_locale, enc);
  			free(quoted_alias);
  		}
--- 1910,1916 ----
  		{
  			char	   *quoted_alias = escape_quotes(alias);
  
! 			PG_CMD_PRINTF3("INSERT INTO tmp_pg_collation VALUES (E'%s', E'%s', %d);\n\n",
  						   quoted_alias, quoted_locale, enc);
  			free(quoted_alias);
  		}
*************** setup_collation(void)
*** 2008,2014 ****
  	}
  
  	/* Add an SQL-standard name */
! 	PG_CMD_PRINTF1("INSERT INTO tmp_pg_collation VALUES ('ucs_basic', 'C', %d);\n", PG_UTF8);
  
  	/*
  	 * When copying collations to the final location, eliminate aliases that
--- 1918,1924 ----
  	}
  
  	/* Add an SQL-standard name */
! 	PG_CMD_PRINTF1("INSERT INTO tmp_pg_collation VALUES ('ucs_basic', 'C', %d);\n\n", PG_UTF8);
  
  	/*
  	 * When copying collations to the final location, eliminate aliases that
*************** setup_collation(void)
*** 2029,2048 ****
  				"   encoding, locale, locale "
  				"  FROM tmp_pg_collation"
  				"  WHERE NOT EXISTS (SELECT 1 FROM pg_collation WHERE collname = tmp_pg_collation.collname)"
! 	   "  ORDER BY collname, encoding, (collname = locale) DESC, locale;\n");
  
  	pclose(locale_a_handle);
- 	PG_CMD_CLOSE;
  
- 	check_ok();
  	if (count == 0 && !debug)
  	{
  		printf(_("No usable system locales were found.\n"));
  		printf(_("Use the option \"--debug\" to see details.\n"));
  	}
- #else							/* not HAVE_LOCALE_T && not WIN32 */
- 	printf(_("not supported on this platform\n"));
- 	fflush(stdout);
  #endif   /* not HAVE_LOCALE_T  && not WIN32 */
  }
  
--- 1939,1953 ----
  				"   encoding, locale, locale "
  				"  FROM tmp_pg_collation"
  				"  WHERE NOT EXISTS (SELECT 1 FROM pg_collation WHERE collname = tmp_pg_collation.collname)"
! 	 "  ORDER BY collname, encoding, (collname = locale) DESC, locale;\n\n");
  
  	pclose(locale_a_handle);
  
  	if (count == 0 && !debug)
  	{
  		printf(_("No usable system locales were found.\n"));
  		printf(_("Use the option \"--debug\" to see details.\n"));
  	}
  #endif   /* not HAVE_LOCALE_T  && not WIN32 */
  }
  
*************** setup_collation(void)
*** 2050,2071 ****
   * load conversion functions
   */
  static void
! setup_conversion(void)
  {
- 	PG_CMD_DECL;
  	char	  **line;
  	char	  **conv_lines;
  
- 	fputs(_("creating conversions ... "), stdout);
- 	fflush(stdout);
- 
- 	snprintf(cmd, sizeof(cmd),
- 			 "\"%s\" %s template1 >%s",
- 			 backend_exec, backend_options,
- 			 DEVNULL);
- 
- 	PG_CMD_OPEN;
- 
  	conv_lines = readfile(conversion_file);
  	for (line = conv_lines; *line != NULL; line++)
  	{
--- 1955,1965 ----
   * load conversion functions
   */
  static void
! setup_conversion(FILE *cmdfd)
  {
  	char	  **line;
  	char	  **conv_lines;
  
  	conv_lines = readfile(conversion_file);
  	for (line = conv_lines; *line != NULL; line++)
  	{
*************** setup_conversion(void)
*** 2075,2109 ****
  	}
  
  	free(conv_lines);
- 
- 	PG_CMD_CLOSE;
- 
- 	check_ok();
  }
  
  /*
   * load extra dictionaries (Snowball stemmers)
   */
  static void
! setup_dictionary(void)
  {
- 	PG_CMD_DECL;
  	char	  **line;
  	char	  **conv_lines;
  
- 	fputs(_("creating dictionaries ... "), stdout);
- 	fflush(stdout);
- 
- 	/*
- 	 * We use -j here to avoid backslashing stuff
- 	 */
- 	snprintf(cmd, sizeof(cmd),
- 			 "\"%s\" %s -j template1 >%s",
- 			 backend_exec, backend_options,
- 			 DEVNULL);
- 
- 	PG_CMD_OPEN;
- 
  	conv_lines = readfile(dictionary_file);
  	for (line = conv_lines; *line != NULL; line++)
  	{
--- 1969,1985 ----
  	}
  
  	free(conv_lines);
  }
  
  /*
   * load extra dictionaries (Snowball stemmers)
   */
  static void
! setup_dictionary(FILE *cmdfd)
  {
  	char	  **line;
  	char	  **conv_lines;
  
  	conv_lines = readfile(dictionary_file);
  	for (line = conv_lines; *line != NULL; line++)
  	{
*************** setup_dictionary(void)
*** 2112,2121 ****
  	}
  
  	free(conv_lines);
- 
- 	PG_CMD_CLOSE;
- 
- 	check_ok();
  }
  
  /*
--- 1988,1993 ----
*************** setup_dictionary(void)
*** 2130,2168 ****
   * set (NOT NULL).
   */
  static void
! setup_privileges(void)
  {
- 	PG_CMD_DECL;
  	char	  **line;
  	char	  **priv_lines;
  	static char *privileges_setup[] = {
  		"UPDATE pg_class "
  		"  SET relacl = E'{\"=r/\\\\\"$POSTGRES_SUPERUSERNAME\\\\\"\"}' "
! 		"  WHERE relkind IN ('r', 'v', 'm', 'S') AND relacl IS NULL;\n",
! 		"GRANT USAGE ON SCHEMA pg_catalog TO PUBLIC;\n",
! 		"GRANT CREATE, USAGE ON SCHEMA public TO PUBLIC;\n",
! 		"REVOKE ALL ON pg_largeobject FROM PUBLIC;\n",
  		NULL
  	};
  
- 	fputs(_("setting privileges on built-in objects ... "), stdout);
- 	fflush(stdout);
- 
- 	snprintf(cmd, sizeof(cmd),
- 			 "\"%s\" %s template1 >%s",
- 			 backend_exec, backend_options,
- 			 DEVNULL);
- 
- 	PG_CMD_OPEN;
- 
  	priv_lines = replace_token(privileges_setup, "$POSTGRES_SUPERUSERNAME",
  							   escape_quotes(username));
  	for (line = priv_lines; *line != NULL; line++)
  		PG_CMD_PUTS(*line);
- 
- 	PG_CMD_CLOSE;
- 
- 	check_ok();
  }
  
  /*
--- 2002,2025 ----
   * set (NOT NULL).
   */
  static void
! setup_privileges(FILE *cmdfd)
  {
  	char	  **line;
  	char	  **priv_lines;
  	static char *privileges_setup[] = {
  		"UPDATE pg_class "
  		"  SET relacl = E'{\"=r/\\\\\"$POSTGRES_SUPERUSERNAME\\\\\"\"}' "
! 		"  WHERE relkind IN ('r', 'v', 'm', 'S') AND relacl IS NULL;\n\n",
! 		"GRANT USAGE ON SCHEMA pg_catalog TO PUBLIC;\n\n",
! 		"GRANT CREATE, USAGE ON SCHEMA public TO PUBLIC;\n\n",
! 		"REVOKE ALL ON pg_largeobject FROM PUBLIC;\n\n",
  		NULL
  	};
  
  	priv_lines = replace_token(privileges_setup, "$POSTGRES_SUPERUSERNAME",
  							   escape_quotes(username));
  	for (line = priv_lines; *line != NULL; line++)
  		PG_CMD_PUTS(*line);
  }
  
  /*
*************** set_info_version(void)
*** 2197,2223 ****
   * load info schema and populate from features file
   */
  static void
! setup_schema(void)
  {
- 	PG_CMD_DECL;
  	char	  **line;
  	char	  **lines;
  
- 	fputs(_("creating information schema ... "), stdout);
- 	fflush(stdout);
- 
  	lines = readfile(info_schema_file);
  
- 	/*
- 	 * We use -j here to avoid backslashing stuff in information_schema.sql
- 	 */
- 	snprintf(cmd, sizeof(cmd),
- 			 "\"%s\" %s -j template1 >%s",
- 			 backend_exec, backend_options,
- 			 DEVNULL);
- 
- 	PG_CMD_OPEN;
- 
  	for (line = lines; *line != NULL; line++)
  	{
  		PG_CMD_PUTS(*line);
--- 2054,2066 ----
   * load info schema and populate from features file
   */
  static void
! setup_schema(FILE *cmdfd)
  {
  	char	  **line;
  	char	  **lines;
  
  	lines = readfile(info_schema_file);
  
  	for (line = lines; *line != NULL; line++)
  	{
  		PG_CMD_PUTS(*line);
*************** setup_schema(void)
*** 2226,2390 ****
  
  	free(lines);
  
- 	PG_CMD_CLOSE;
- 
- 	snprintf(cmd, sizeof(cmd),
- 			 "\"%s\" %s template1 >%s",
- 			 backend_exec, backend_options,
- 			 DEVNULL);
- 
- 	PG_CMD_OPEN;
- 
  	PG_CMD_PRINTF1("UPDATE information_schema.sql_implementation_info "
  				   "  SET character_value = '%s' "
! 				   "  WHERE implementation_info_name = 'DBMS VERSION';\n",
  				   infoversion);
  
  	PG_CMD_PRINTF1("COPY information_schema.sql_features "
  				   "  (feature_id, feature_name, sub_feature_id, "
  				   "  sub_feature_name, is_supported, comments) "
! 				   " FROM E'%s';\n",
  				   escape_quotes(features_file));
- 
- 	PG_CMD_CLOSE;
- 
- 	check_ok();
  }
  
  /*
   * load PL/pgsql server-side language
   */
  static void
! load_plpgsql(void)
  {
! 	PG_CMD_DECL;
! 
! 	fputs(_("loading PL/pgSQL server-side language ... "), stdout);
! 	fflush(stdout);
! 
! 	snprintf(cmd, sizeof(cmd),
! 			 "\"%s\" %s template1 >%s",
! 			 backend_exec, backend_options,
! 			 DEVNULL);
! 
! 	PG_CMD_OPEN;
! 
! 	PG_CMD_PUTS("CREATE EXTENSION plpgsql;\n");
! 
! 	PG_CMD_CLOSE;
! 
! 	check_ok();
  }
  
  /*
   * clean everything up in template1
   */
  static void
! vacuum_db(void)
  {
- 	PG_CMD_DECL;
- 
- 	fputs(_("vacuuming database template1 ... "), stdout);
- 	fflush(stdout);
- 
- 	snprintf(cmd, sizeof(cmd),
- 			 "\"%s\" %s template1 >%s",
- 			 backend_exec, backend_options,
- 			 DEVNULL);
- 
- 	PG_CMD_OPEN;
- 
  	/* Run analyze before VACUUM so the statistics are frozen. */
! 	PG_CMD_PUTS("ANALYZE;\nVACUUM FREEZE;\n");
! 
! 	PG_CMD_CLOSE;
! 
! 	check_ok();
  }
  
  /*
   * copy template1 to template0
   */
  static void
! make_template0(void)
  {
! 	PG_CMD_DECL;
! 	const char **line;
! 	static const char *template0_setup[] = {
! 		"CREATE DATABASE template0 IS_TEMPLATE = true ALLOW_CONNECTIONS = false;\n",
  
  		/*
  		 * We use the OID of template0 to determine lastsysoid
  		 */
  		"UPDATE pg_database SET datlastsysoid = "
  		"    (SELECT oid FROM pg_database "
! 		"    WHERE datname = 'template0');\n",
  
  		/*
  		 * Explicitly revoke public create-schema and create-temp-table
  		 * privileges in template1 and template0; else the latter would be on
  		 * by default
  		 */
! 		"REVOKE CREATE,TEMPORARY ON DATABASE template1 FROM public;\n",
! 		"REVOKE CREATE,TEMPORARY ON DATABASE template0 FROM public;\n",
  
! 		"COMMENT ON DATABASE template0 IS 'unmodifiable empty database';\n",
  
  		/*
  		 * Finally vacuum to clean up dead rows in pg_database
  		 */
! 		"VACUUM FULL pg_database;\n",
  		NULL
  	};
  
- 	fputs(_("copying template1 to template0 ... "), stdout);
- 	fflush(stdout);
- 
- 	snprintf(cmd, sizeof(cmd),
- 			 "\"%s\" %s template1 >%s",
- 			 backend_exec, backend_options,
- 			 DEVNULL);
- 
- 	PG_CMD_OPEN;
- 
  	for (line = template0_setup; *line; line++)
  		PG_CMD_PUTS(*line);
- 
- 	PG_CMD_CLOSE;
- 
- 	check_ok();
  }
  
  /*
   * copy template1 to postgres
   */
  static void
! make_postgres(void)
  {
! 	PG_CMD_DECL;
! 	const char **line;
! 	static const char *postgres_setup[] = {
! 		"CREATE DATABASE postgres;\n",
! 		"COMMENT ON DATABASE postgres IS 'default administrative connection database';\n",
  		NULL
  	};
  
- 	fputs(_("copying template1 to postgres ... "), stdout);
- 	fflush(stdout);
- 
- 	snprintf(cmd, sizeof(cmd),
- 			 "\"%s\" %s template1 >%s",
- 			 backend_exec, backend_options,
- 			 DEVNULL);
- 
- 	PG_CMD_OPEN;
- 
  	for (line = postgres_setup; *line; line++)
  		PG_CMD_PUTS(*line);
- 
- 	PG_CMD_CLOSE;
- 
- 	check_ok();
  }
  
  /*
--- 2069,2158 ----
  
  	free(lines);
  
  	PG_CMD_PRINTF1("UPDATE information_schema.sql_implementation_info "
  				   "  SET character_value = '%s' "
! 				   "  WHERE implementation_info_name = 'DBMS VERSION';\n\n",
  				   infoversion);
  
  	PG_CMD_PRINTF1("COPY information_schema.sql_features "
  				   "  (feature_id, feature_name, sub_feature_id, "
  				   "  sub_feature_name, is_supported, comments) "
! 				   " FROM E'%s';\n\n",
  				   escape_quotes(features_file));
  }
  
  /*
   * load PL/pgsql server-side language
   */
  static void
! load_plpgsql(FILE *cmdfd)
  {
! 	PG_CMD_PUTS("CREATE EXTENSION plpgsql;\n\n");
  }
  
  /*
   * clean everything up in template1
   */
  static void
! vacuum_db(FILE *cmdfd)
  {
  	/* Run analyze before VACUUM so the statistics are frozen. */
! 	PG_CMD_PUTS("ANALYZE;\n\nVACUUM FREEZE;\n\n");
  }
  
  /*
   * copy template1 to template0
   */
  static void
! make_template0(FILE *cmdfd)
  {
! 	const char *const * line;
! 	static const char *const template0_setup[] = {
! 		"CREATE DATABASE template0 IS_TEMPLATE = true ALLOW_CONNECTIONS = false;\n\n",
  
  		/*
  		 * We use the OID of template0 to determine lastsysoid
  		 */
  		"UPDATE pg_database SET datlastsysoid = "
  		"    (SELECT oid FROM pg_database "
! 		"    WHERE datname = 'template0');\n\n",
  
  		/*
  		 * Explicitly revoke public create-schema and create-temp-table
  		 * privileges in template1 and template0; else the latter would be on
  		 * by default
  		 */
! 		"REVOKE CREATE,TEMPORARY ON DATABASE template1 FROM public;\n\n",
! 		"REVOKE CREATE,TEMPORARY ON DATABASE template0 FROM public;\n\n",
  
! 		"COMMENT ON DATABASE template0 IS 'unmodifiable empty database';\n\n",
  
  		/*
  		 * Finally vacuum to clean up dead rows in pg_database
  		 */
! 		"VACUUM FULL pg_database;\n\n",
  		NULL
  	};
  
  	for (line = template0_setup; *line; line++)
  		PG_CMD_PUTS(*line);
  }
  
  /*
   * copy template1 to postgres
   */
  static void
! make_postgres(FILE *cmdfd)
  {
! 	const char *const * line;
! 	static const char *const postgres_setup[] = {
! 		"CREATE DATABASE postgres;\n\n",
! 		"COMMENT ON DATABASE postgres IS 'default administrative connection database';\n\n",
  		NULL
  	};
  
  	for (line = postgres_setup; *line; line++)
  		PG_CMD_PUTS(*line);
  }
  
  /*
*************** check_authmethod_unspecified(const char 
*** 2794,2802 ****
  }
  
  static void
! check_authmethod_valid(const char *authmethod, const char **valid_methods, const char *conntype)
  {
! 	const char **p;
  
  	for (p = valid_methods; *p; p++)
  	{
--- 2562,2570 ----
  }
  
  static void
! check_authmethod_valid(const char *authmethod, const char *const * valid_methods, const char *conntype)
  {
! 	const char *const * p;
  
  	for (p = valid_methods; *p; p++)
  	{
*************** warn_on_mount_point(int error)
*** 3303,3308 ****
--- 3071,3077 ----
  void
  initialize_data_directory(void)
  {
+ 	PG_CMD_DECL;
  	int			i;
  
  	setup_signals();
*************** initialize_data_directory(void)
*** 3343,3377 ****
  	 */
  	write_version_file("base/1");
  
! 	/* Create the stuff we don't need to use bootstrap mode for */
  
! 	setup_auth();
  	if (pwprompt || pwfilename)
! 		get_set_pwd();
  
! 	setup_depend();
  
! 	setup_sysviews();
  
! 	setup_description();
  
! 	setup_collation();
  
! 	setup_conversion();
  
! 	setup_dictionary();
  
! 	setup_privileges();
  
! 	setup_schema();
  
! 	load_plpgsql();
  
! 	vacuum_db();
  
! 	make_template0();
  
! 	make_postgres();
  }
  
  
--- 3112,3162 ----
  	 */
  	write_version_file("base/1");
  
! 	/*
! 	 * Create the stuff we don't need to use bootstrap mode for, using a
! 	 * backend running in simple standalone mode.
! 	 */
! 	fputs(_("performing post-bootstrap initialization ... "), stdout);
! 	fflush(stdout);
  
! 	snprintf(cmd, sizeof(cmd),
! 			 "\"%s\" %s template1 >%s",
! 			 backend_exec, backend_options,
! 			 DEVNULL);
! 
! 	PG_CMD_OPEN;
! 
! 	setup_auth(cmdfd);
  	if (pwprompt || pwfilename)
! 		get_set_pwd(cmdfd);
  
! 	setup_depend(cmdfd);
  
! 	setup_sysviews(cmdfd);
  
! 	setup_description(cmdfd);
  
! 	setup_collation(cmdfd);
  
! 	setup_conversion(cmdfd);
  
! 	setup_dictionary(cmdfd);
  
! 	setup_privileges(cmdfd);
  
! 	setup_schema(cmdfd);
  
! 	load_plpgsql(cmdfd);
  
! 	vacuum_db(cmdfd);
  
! 	make_template0(cmdfd);
  
! 	make_postgres(cmdfd);
! 
! 	PG_CMD_CLOSE;
! 
! 	check_ok();
  }
  
  
diff --git a/src/tools/msvc/Install.pm b/src/tools/msvc/Install.pm
index f955725..40e06f6 100644
*** a/src/tools/msvc/Install.pm
--- b/src/tools/msvc/Install.pm
*************** sub GenerateConversionScript
*** 365,371 ****
  		$sql .=
  "CREATE DEFAULT CONVERSION pg_catalog.$name FOR '$se' TO '$de' FROM $func;\n";
  		$sql .=
! "COMMENT ON CONVERSION pg_catalog.$name IS 'conversion for $se to $de';\n";
  	}
  	open($F, ">$target/share/conversion_create.sql")
  	  || die "Could not write to conversion_create.sql\n";
--- 365,371 ----
  		$sql .=
  "CREATE DEFAULT CONVERSION pg_catalog.$name FOR '$se' TO '$de' FROM $func;\n";
  		$sql .=
! "COMMENT ON CONVERSION pg_catalog.$name IS 'conversion for $se to $de';\n\n";
  	}
  	open($F, ">$target/share/conversion_create.sql")
  	  || die "Could not write to conversion_create.sql\n";
-- 
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