Re: Using a single standalone-backend run in initdb (was Re: Bootstrap DATA is a pita)

Поиск
Список
Период
Сортировка
От Tom Lane
Тема Re: Using a single standalone-backend run in initdb (was Re: Bootstrap DATA is a pita)
Дата
Msg-id 6322.1450369168@sss.pgh.pa.us
обсуждение исходный текст
Ответ на Re: Using a single standalone-backend run in initdb (was Re: Bootstrap DATA is a pita)  (Mark Dilger <hornschnorter@gmail.com>)
Список pgsql-hackers
Mark Dilger <hornschnorter@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";

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Aleksander Alekseev
Дата:
Сообщение: Re: Patch: fix lock contention for HASHHDR.mutex
Следующее
От: Jeff Janes
Дата:
Сообщение: Fwd: Cluster "stuck" in "not accepting commands to avoid wraparound data loss"