]> granicus.if.org Git - postgresql/commitdiff
Add option to output SET SESSION AUTHORIZATION commands rather than
authorPeter Eisentraut <peter_e@gmx.net>
Wed, 22 Aug 2001 20:23:24 +0000 (20:23 +0000)
committerPeter Eisentraut <peter_e@gmx.net>
Wed, 22 Aug 2001 20:23:24 +0000 (20:23 +0000)
\connect, to avoid possible password prompts and such, at the drawback of
having to have superuser access.

doc/src/sgml/ref/pg_dump.sgml
doc/src/sgml/ref/pg_restore.sgml
src/bin/pg_dump/pg_backup.h
src/bin/pg_dump/pg_backup_archiver.c
src/bin/pg_dump/pg_backup_archiver.h
src/bin/pg_dump/pg_backup_db.c
src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dump.h
src/bin/pg_dump/pg_restore.c

index 2eec491cd42ee8f294f0274caa53a0b67fcf25a6..1da554aa70e5b31c4e28e20209c53a0d7db8f95c 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_dump.sgml,v 1.34 2001/08/12 19:02:39 petere Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_dump.sgml,v 1.35 2001/08/22 20:23:23 petere Exp $
 Postgres documentation
 -->
 
@@ -43,6 +43,7 @@ Postgres documentation
    <arg>-t <replaceable>table</replaceable></arg>
    <arg>-v</arg>
    <arg>-x</arg>
+   <arg>-X <replaceable>keyword</replaceable></arg>
    <arg>-Z <replaceable>0...9</replaceable></arg>
    <arg>-h <replaceable>host</replaceable></arg>
    <arg>-p <replaceable>port</replaceable></arg>
@@ -59,44 +60,56 @@ Postgres documentation
   </title>
 
   <para>
-   <command>pg_dump</command> is a utility for dumping out a 
-   <productname>Postgres</productname> database into a script or archive 
-   file containing query commands. The script files are in text format 
-   and can be used to reconstruct the database, even on other machines 
-   and other architectures.
-   The archive files, new with version 7.1, contain enough information for 
-   <xref linkend="app-pgrestore"> to rebuild the database, but also
-   allow <command>pg_restore</command> to be selective about what is restored, or even to 
-   reorder the items prior to being restored. The archive files are
-   also designed to be portable across architectures.
+   <command>pg_dump</command> is a utility for saving a
+   <productname>PostgreSQL</productname> database into a script or an
+   archive file.  The script files are in plain text format and
+   contain the SQL commands required to reconstruct the database to
+   the state it was in at the time is was saved.  They can be used to
+   reconstruct the database even on other machines and other
+   architectures, with some modifications even on other RDBMS
+   products.  The alternative archive file formats are meant to be
+   used with <xref linkend="app-pgrestore"> to rebuild the database,
+   and they also allow <command>pg_restore</command> to be selective
+   about what is restored, or even to reorder the items prior to being
+   restored. The archive files are also designed to be portable across
+   architectures.
   </para>
 
   <para>
-   <command>pg_dump</command> 
-   will produce the queries necessary to re-generate all
-   user-defined types, functions, tables, indexes, aggregates, and
-   operators.  In addition, all the data is copied out in text format so
-   that it can be readily copied in again, as well as imported into tools
-   for editing.
+   <command>pg_dump</command> will save the information necessary to
+   re-generate all user-defined types, functions, tables, indexes,
+   aggregates, and operators.  In addition, all the data is copied out
+   in text format so that it can be readily copied in again, as well
+   as imported into tools for editing.
   </para>
 
   <para>
    <command>pg_dump</command> 
    is useful for dumping out the contents of a database to move from one
-   <productname>Postgres</productname> installation to another.  After running 
-   <command>pg_dump</command>,
-   one should examine the output for any warnings, especially
-   in light of the limitations listed below. 
+   <productname>Postgres</productname> installation to another.
   </para>
 
   <para>
-   When used with one of the alternate file formats and combined with 
-   <command>pg_restore</command>, it provides a flexible archival 
-   and transfer mechanism. <command>pg_dump</command> can be used 
-   to backup an entire database, then <command>pg_restore</command> 
-   can be used to examine the archive and/or select which parts of the 
-   database are to be restored.
-   See the <xref linkend="app-pgrestore"> documentation for details.
+   When used with one of the archive file formats and combined with
+   <command>pg_restore</command>, it provides a flexible archival and
+   transfer mechanism. <command>pg_dump</command> can be used to
+   backup an entire database, then <command>pg_restore</command> can
+   be used to examine the archive and/or select which parts of the
+   database are to be restored.  See the <xref
+   linkend="app-pgrestore"> documentation for details.
+  </para>
+
+  <para>
+   While running <command>pg_dump</command>, one should examine the
+   output for any warnings (printed on standard error), especially in
+   light of the limitations listed below.
+  </para>
+
+  <para>
+   <command>pg_dump</command> makes consistent backups even if the
+   database is being used concurrently.  <command>pg_dump</command>
+   does not block other users accessing the database (readers or
+   writers).
   </para>
 
   <refsect2 id="pg-dump-options">
@@ -141,7 +154,7 @@ Postgres documentation
       <term>--clean</term>
       <listitem>
        <para>
-        Dump commands to clean (drop) the schema prior to (the
+        Output commands to clean (drop) the schema prior to (the
         commands for) creating it.
        </para>
       </listitem>
@@ -162,9 +175,10 @@ Postgres documentation
       <term>--inserts</term>
       <listitem>
        <para>
-       Dump data as proper <command>INSERT</command> commands (not
-       <command>COPY</command>). This will make restoration very
-       slow.
+       Dump data as proper <command>INSERT</command> commands (rather
+       than <command>COPY</command>). This will make restoration very
+       slow, but it makes the archives more portable to other RDBMS
+       packages.
        </para>
       </listitem>
      </varlistentry>
@@ -189,7 +203,8 @@ Postgres documentation
       <term>--file=<replaceable class="parameter">file</replaceable></term>
       <listitem>
        <para>
-       Send output to the specified file.
+       Send output to the specified file.  If this is omitted, the
+       standard output is used.
        </para>
       </listitem>
      </varlistentry>
@@ -199,7 +214,8 @@ Postgres documentation
       <term>--format=<replaceable class="parameter">format</replaceable></term>
       <listitem>
        <para>
-       Format can be one of the following:
+        Selects the format of the output.
+       <replaceable>format</replaceable> can be one of the following:
 
        <variablelist>
         <varlistentry>
@@ -289,7 +305,10 @@ Postgres documentation
       <term>--oids</term>
       <listitem>
        <para>
-       Dump object identifiers (<acronym>OID</acronym>s) for every table.
+       Dump object identifiers (<acronym>OID</acronym>s) for every
+       table.  Use this option if your application references the oid
+       columns in some way (e.g., in a foreign key constraint).
+       Otherwise, this option should not be used.
        </para>
       </listitem>
      </varlistentry>
@@ -299,11 +318,22 @@ Postgres documentation
       <term>--no-owner</term>
       <listitem>
        <para>
-       In plain text output mode, do not set object ownership to
-        match the original database. Typically,
-        <command>pg_dump</command> issues
-        (<command>psql</command>-specific) <command>\connect</command>
-        statements to set ownership of schema elements.
+       In plain text output mode, do not output commands to set the
+       object ownership to match the original database.  Typically,
+       <command>pg_dump</command> issues
+       (<command>psql</command>-specific) <command>\connect</command>
+       statements to set ownership of schema elements.  See also
+       under <option>-R</option> and <option>-X
+       use-set-session-authorization</option>.  Note that
+       <option>-O</option> does not prevent all reconnections to the
+       database, only the ones that are exclusively used for
+       ownership adjustments.
+       </para>
+
+       <para>
+        This option is only meaningful for the plain text format.  For
+        the other formats, you need to specify the option when you
+        call <command>pg_restore</command>.
        </para>
       </listitem>
      </varlistentry>
@@ -313,8 +343,27 @@ Postgres documentation
       <term>--no-reconnect</term>
       <listitem>
        <para>
-       In plain text output mode, prohibit <command>pg_dump</command> 
-        from issuing any <command>\connect</command> statements.
+       In plain text output mode, prohibit <command>pg_dump</command>
+        from outputting a script that would require reconnections to
+        the database while being restored.  An average restoration
+        script usually has to reconnect several times as different
+        users to set the original ownerships of the objects.  This
+        option is a rather blunt instrument because it makes
+        <command>pg_dump</command> lose this ownership information,
+        <emphasis>unless</emphasis> you use the <option>-X
+        use-set-session-authorization</option> option.
+       </para>
+
+       <para>
+        One possible reason why reconnections during restore might not
+        be desired is if the access to the database requires manual
+        interaction (e.g., passwords).
+       </para>
+
+       <para>
+        This option is only meaningful for the plain text format.  For
+        the other formats, you need to specify the option when you
+        call <command>pg_restore</command>.
        </para>
       </listitem>
      </varlistentry>
@@ -334,8 +383,10 @@ Postgres documentation
       <term>--superuser=<replaceable class="parameter">username</replaceable></term>
       <listitem>
        <para>
-       Specify the superuser user name to use when disabling triggers and/or 
-      setting ownership of schema elements.
+        The scripts or archives created by <command>pg_dump</command>
+        need to have superuser access in certain cases, such as when
+        disabling triggers or setting ownership of schema elements.
+        This option specifies the user name to use for those cases.
        </para>
       </listitem>
      </varlistentry>
@@ -366,8 +417,42 @@ Postgres documentation
       <term>--no-acl</term>
       <listitem>
        <para>
-       Prevent dumping of access privileges (grant/revoke commands)
-       and table ownership information.
+       Prevent dumping of access privileges (grant/revoke commands).
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term>-X use-set-session-authorization</term>
+      <term>--use-set-session-authorization</term>
+      <listitem>
+       <para>
+        Normally, if a (plain text mode) script generated by
+        <command>pg_dump</command> must alter the current database
+        user (e.g., to set correct object ownerships), it uses the
+        <xref linkend="app-psql"> <command>\connect</command> command.
+        This command actually opens a new connection, which might
+        require manual interaction (e.g., passwords).  If you use the
+        <option>-X use-set-session-authorization</option>, then
+        <command>pg_dump</command> will instead output <xref
+        linkend="sql-set-session-authorization"> commands.  This has
+        the same effect, but it requires that the user restoring the
+        database from the generated script be a database superuser.
+        This option effectively overrides the <option>-R</option>
+        option.
+       </para>
+
+       <para>
+        Since <xref linkend="sql-set-session-authorization"> is a
+        standard SQL command, whereas <command>\connect</command> only
+        works in <xref linkend="app-psql">, this option also enhances
+        the theoretical portability of the output script.
+       </para>
+
+       <para>
+        This option is only meaningful for the plain text format.  For
+        the other formats, you need to specify the option when you
+        call <command>pg_restore</command>.
        </para>
       </listitem>
      </varlistentry>
@@ -442,7 +527,6 @@ Postgres documentation
 
  </refsect1>
 
-
  <refsect1 id="app-pgdump-diagnostics">
   <title>Diagnostics</title>
 
@@ -551,6 +635,17 @@ connectDBStart() -- connect() failed: No such file or directory
 
  </refsect1>
 
+ <refsect1>
+  <title>History</title>
+
+  <para>
+   The <command>pg_dump</command> utility first appeared in
+   <application>Postgres95 release 0.02</application>.  The
+   non-plain-text output formats were introduced in
+   <application>PostgreSQL 7.1</application>.
+  </para>
+ </refsect1>
+
  <refsect1>
   <title>See Also</title>
 
index 0acb3fb1512503e970a7505c5ea354f1009b5f43..22f264ceac18a60a638c60519c9459def725f12e 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_restore.sgml,v 1.13 2001/08/12 19:02:39 petere Exp $ -->
+<!-- $Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_restore.sgml,v 1.14 2001/08/22 20:23:23 petere Exp $ -->
 
 <refentry id="APP-PGRESTORE">
  <docinfo>
@@ -44,6 +44,7 @@
    <arg> -T  <replaceable class="parameter">trigger</replaceable> </arg>
    <arg> -v </arg>
    <arg> -x </arg>
+   <arg> -X <replaceable>keyword</replaceable></arg>
    <arg> -h  <replaceable class="parameter">host</replaceable> </arg>
    <arg> -p  <replaceable class="parameter">port</replaceable> </arg>
    <arg> -U <replaceable>username</replaceable> </arg>
 
   <para>
    <command>pg_restore</command> is a utility for restoring a
-   <productname>Postgres</productname> database dumped by
-   <xref linkend="app-pgdump"> in one of the non-plain-text formats.
+   <productname>Postgres</productname> database from an archive
+   created by <xref linkend="app-pgdump"> in one of the non-plain-text
+   formats.
   </para>
 
   <para>
-   The archive files, new with the 7.1 release, contain enough information for
-   <command>pg_restore</command> to rebuild the database, but also allow
-   <command>pg_restore</command> to be selective about what is restored,
-   or even to reorder the items prior to being restored. The archive files are designed
-   to be portable across architectures. <command>pg_dump</command> will
-   produce the queries necessary to re-generate all user-defined types, functions,
-   tables, indexes, aggregates, and operators.  In addition, all the data is copied
-   out (in text format for scripts) so that it can be readily copied in again.
+   The archive files contain information for
+   <command>pg_restore</command> to rebuild the database, but also
+   allow <command>pg_restore</command> to be selective about what is
+   restored, or even to reorder the items prior to being restored. The
+   archive files are designed to be portable across architectures.  It
+   will issue the commands necessary to re-generate all user-defined
+   types, functions, tables, indexes, aggregates, and operators, as
+   well as the data in the tables.
   </para>
 
   <para>
-   <command>pg_restore</command> reads the archive file and outputs the appropriate
-   SQL in the required order based on the command parameters. Obviously, it can not restore
-   information that is not present in the dump file; so if the dump is made using the
-   <quote>dump data as <command>INSERT</command>s</quote> option, <command>pg_restore</command> will not be able to
-   load the data using <command>COPY</command> statements.
+   <command>pg_restore</command> can operate in two modes:  If a
+   database name is specified, the archive is restored directly into
+   the database.  Otherwise, a script containing the SQL commands
+   necessary to rebuild the database is created (and written to a file
+   or standard output), similar to the ones created by the
+   <command>pg_dump</command> plain text format.  Some of the options
+   controlling the script output are therefore analogous to
+   <command>pg_dump</command>.
   </para>
 
   <para>
-   The most flexible output file format is the <quote>custom</quote> format (<option>-Fc</option>). It allows for
-   selection and reordering of all archived items, and is compressed by default. The <filename>tar</filename>
-   format (<option>-Ft</option>) is not compressed and it is not possible to reorder
-   data when loading, but it is otherwise quite flexible.
+   Obviously, <command>pg_restore</command> cannot restore information
+   that is not present in the archive file; for instance, if the
+   archive was made using the <quote>dump data as
+   <command>INSERT</command>s</quote> option,
+   <command>pg_restore</command> will not be able to load the data
+   using <command>COPY</command> statements.
   </para>
 
   <para>
-   To reorder the items, it is first necessary to dump the contents of the archive:
+   The most flexible output file format is the <quote>custom</quote>
+   format (<option>-Fc</option>). It allows for selection and
+   reordering of all archived items, and is compressed by default. The
+   <filename>tar</filename> format (<option>-Ft</option>) is not
+   compressed and it is not possible to reorder data when loading, but
+   it is otherwise quite flexible.
+  </para>
+
+  <para>
+   To reorder the items, it is first necessary to dump the table of
+   contents of the archive:
 <screen>
 <prompt>$</prompt> <userinput>pg_restore archive.file -l &gt; archive.list</userinput>
 </screen>
       <term>--no-reconnect</term>
       <listitem>
        <para>
-         Prohibit <COMMAND>pg_restore</COMMAND> from issuing any <PROGRAMLISTING>\connect</PROGRAMLISTING>
-        statements or reconnecting to the database if directly connected.
+        While restoring an archive, <command>pg_restore</command>
+        typically has to reconnect to the database several times with
+        different user names to set the correct ownership of the
+        created objects.  If this is undesriable (e.g., because manual
+        interaction (passwords) would be necessary for each
+        reconnection), this option prevents
+        <command>pg_restore</command> from issuing any reconnection
+        requests.  (A connection request while in plain text mode, not
+        connected to a database, is made by putting out a <xref
+        linkend="app-psql"> <command>\connect</command> command.)
+        However, this option is a rather blunt instrument because it
+        makes <command>pg_restore</command> lose all object ownership
+        information, <emphasis>unless</emphasis> you use the
+        <option>-X use-set-session-authorization</option> option.
        </para>
       </listitem>
      </varlistentry>
       </listitem>
      </varlistentry>
 
+     <varlistentry>
+      <term>-X use-set-session-authorization</term>
+      <term>--use-set-session-authorization</term>
+      <listitem>
+       <para>
+        Normally, if restoring an archive requires altering the
+        current database user (e.g., to set correct object
+        ownerships), a new connection to the database must be openend,
+        which might require manual interaction (e.g., passwords).  If
+        you use the <option>-X use-set-session-authorization</option>,
+        then <command>pg_restore</command> will instead use the <xref
+        linkend="sql-set-session-authorization"> command.  This has
+        the same effect, but it requires that the user restoring the
+        archive is a database superuser.  This option effectively
+        overrides the <option>-R</option> option.
+       </para>
+      </listitem>
+     </varlistentry>
+
     </variablelist>
    </para>
 
@@ -592,6 +640,14 @@ connectDBStart() -- connect() failed: No such file or directory
 
  </refsect1>
 
+ <refsect1>
+  <title>History</title>
+
+  <para>
+   The <command>pg_restore</command> utility first appeared in
+   PostgreSQL 7.1.
+  </para>
+ </refsect1>
 
  <refsect1>
   <title>See Also</title>
index 7e555957eb082c9e05b2050a68e9222ed80d9657..282738d882d17077ba23e34e5a73bebec9d843b4 100644 (file)
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *             $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup.h,v 1.13 2001/06/27 21:21:37 petere Exp $
+ *             $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup.h,v 1.14 2001/08/22 20:23:23 petere Exp $
  *
  * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
  *
@@ -85,6 +85,7 @@ typedef struct _restoreOptions
                                                                 * original object owner */
        int                     noReconnect;    /* Don't reconnect to database under any
                                                                 * cirsumstances */
+       int                     use_setsessauth; /* use SET SESSSION AUTHORIZATION instead of \connect */
        char       *superuser;          /* Username to use as superuser */
        int                     dataOnly;
        int                     dropSchema;
index 982cabbcf2cdf160653470a0a07665005e0297ab..4ada30994f2e73793febf00399b3003e646a69b9 100644 (file)
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *             $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.31 2001/08/19 22:17:03 petere Exp $
+ *             $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.32 2001/08/22 20:23:23 petere Exp $
  *
  * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
  *
@@ -78,7 +78,7 @@ static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
 static int     _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData);
 
 static void _reconnectAsOwner(ArchiveHandle *AH, const char *dbname, TocEntry *te);
-static void _reconnectAsUser(ArchiveHandle *AH, const char *dbname, char *user);
+static void _reconnectAsUser(ArchiveHandle *AH, const char *dbname, const char *user);
 
 static int     _tocEntryRequired(TocEntry *te, RestoreOptions *ropt);
 static void _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
@@ -251,7 +251,7 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
                                /* We want the schema */
                                ahlog(AH, 1, "dropping %s %s\n", te->desc, te->name);
                                /* Reconnect if necessary */
-                               _reconnectAsOwner(AH, "-", te);
+                               _reconnectAsOwner(AH, NULL, te);
                                /* Drop it */
                                ahprintf(AH, "%s", te->dropStmt);
                        }
@@ -283,7 +283,7 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
                if ((reqs & 1) != 0)    /* We want the schema */
                {
                        /* Reconnect if necessary */
-                       _reconnectAsOwner(AH, "-", te);
+                       _reconnectAsOwner(AH, NULL, te);
 
                        ahlog(AH, 1, "creating %s %s\n", te->desc, te->name);
                        _printTocEntry(AH, te, ropt, false);
@@ -345,7 +345,7 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
                                                 * Reconnect if necessary (_disableTriggers may have
                                                 * reconnected)
                                                 */
-                                               _reconnectAsOwner(AH, "-", te);
+                                               _reconnectAsOwner(AH, NULL, te);
 
                                                ahlog(AH, 1, "restoring data for table %s\n", te->name);
 
@@ -448,6 +448,10 @@ NewRestoreOptions(void)
        return opts;
 }
 
+/*
+ * Returns true if we're restoring directly to the database (and
+ * aren't just making a psql script that can do the restoration).
+ */
 static int
 _restoringToDB(ArchiveHandle *AH)
 {
@@ -486,7 +490,7 @@ _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *rop
                         */
                        if (ropt->noOwner)
                                oldUser = strdup(ConnectedUser(AH));
-                       _reconnectAsUser(AH, "-", ropt->superuser);
+                       _reconnectAsUser(AH, NULL, ropt->superuser);
                }
        }
 
@@ -514,7 +518,7 @@ _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *rop
         */
        if (ropt->noOwner && oldUser)
        {
-               _reconnectAsUser(AH, "-", oldUser);
+               _reconnectAsUser(AH, NULL, oldUser);
                free(oldUser);
        }
 }
@@ -546,7 +550,7 @@ _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt
                        if (ropt->noOwner)
                                oldUser = strdup(ConnectedUser(AH));
 
-                       _reconnectAsUser(AH, "-", ropt->superuser);
+                       _reconnectAsUser(AH, NULL, ropt->superuser);
                }
        }
 
@@ -577,7 +581,7 @@ _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt
         */
        if (ropt->noOwner && oldUser)
        {
-               _reconnectAsUser(AH, "-", oldUser);
+               _reconnectAsUser(AH, NULL, oldUser);
                free(oldUser);
        }
 }
@@ -1895,26 +1899,71 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt)
        return res;
 }
 
+
+/*
+ * Issue the commands to connect to the database as the specified user
+ * to the specified database.  The database name may be NULL, then the
+ * current database is kept.  If reconnects were disallowed by the
+ * user, this won't do anything.
+ *
+ * If we're currently restoring right into a database, this will
+ * actuall establish a connection.  Otherwise it puts a \connect into
+ * the script output.
+ */
 static void
-_reconnectAsUser(ArchiveHandle *AH, const char *dbname, char *user)
+_reconnectAsUser(ArchiveHandle *AH, const char *dbname, const char *user)
 {
-       if (AH->ropt && AH->ropt->noReconnect)
-               return;
+       if (!user || strlen(user) == 0
+               || (strcmp(AH->currUser, user) == 0 && !dbname))
+               return;                                 /* no need to do anything */
 
-       if (user && strlen(user) != 0
-       && ((strcmp(AH->currUser, user) != 0) || (strcmp(dbname, "-") != 0)))
+       /* Use SET SESSION AUTHORIZATION if allowed and no database change needed */
+       if (!dbname && AH->ropt->use_setsessauth)
        {
                if (RestoringToDB(AH))
-                       ReconnectDatabase(AH, dbname, user);
-               else
-                       ahprintf(AH, "\\connect %s %s\n", dbname, user);
-               if (AH->currUser)
-                       free(AH->currUser);
+               {
+                       PQExpBuffer qry = createPQExpBuffer();
+                       PGresult   *res;
+
+                       appendPQExpBuffer(qry, "SET SESSION AUTHORIZATION '%s';", user);
+                       res = PQexec(AH->connection, qry->data);
+
+                       if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
+                               die_horribly(AH, modulename, "could not set session user to %s: %s",
+                                                        user, PQerrorMessage(AH->connection));
 
-               AH->currUser = strdup(user);
+                       PQclear(res);
+                       destroyPQExpBuffer(qry);
+               }
+               else
+                       ahprintf(AH, "SET SESSION AUTHORIZATION '%s';\n\n", user);
        }
+       /* When -R was given, don't do anything. */
+       else if (AH->ropt && AH->ropt->noReconnect)
+               return;
+
+       else if (RestoringToDB(AH))
+               ReconnectToServer(AH, dbname, user);
+       else
+               /* FIXME: does not handle mixed case user names */
+               ahprintf(AH, "\\connect %s %s\n\n",
+                                dbname ? dbname : "-",
+                                user ? user : "-");
+
+       /* NOTE: currUser keeps track of what the imaginary session user
+       in our script is */
+       if (AH->currUser)
+               free(AH->currUser);
+
+       AH->currUser = strdup(user);
 }
 
+
+/*
+ * Issues the commands to connect to the database (or the current one,
+ * if NULL) as the owner of the the given TOC entry object.  If
+ * changes in ownership are not allowed, this doesn't do anything.
+ */
 static void
 _reconnectAsOwner(ArchiveHandle *AH, const char *dbname, TocEntry *te)
 {
@@ -1924,6 +1973,7 @@ _reconnectAsOwner(ArchiveHandle *AH, const char *dbname, TocEntry *te)
        _reconnectAsUser(AH, dbname, te->owner);
 }
 
+
 static int
 _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData)
 {
index 16a1c06dfe6ebea7b0e93c3248f3f64de97479a7..fee94d83b0fd39d8c9985086b97dc9939081ef2b 100644 (file)
@@ -17,7 +17,7 @@
  *
  *
  * IDENTIFICATION
- *             $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.36 2001/07/03 20:21:48 petere Exp $
+ *             $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.37 2001/08/22 20:23:23 petere Exp $
  *
  * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
  *     -       Initial version.
@@ -310,7 +310,7 @@ extern int  isValidTarHeader(char *header);
 extern OutputContext SetOutput(ArchiveHandle *AH, char *filename, int compression);
 extern void ResetOutput(ArchiveHandle *AH, OutputContext savedContext);
 extern int     RestoringToDB(ArchiveHandle *AH);
-extern int     ReconnectDatabase(ArchiveHandle *AH, const char *dbname, char *newUser);
+extern int     ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *newUser);
 extern int     UserIsSuperuser(ArchiveHandle *AH, char *user);
 extern char *ConnectedUser(ArchiveHandle *AH);
 extern int     ConnectedUserIsSuperuser(ArchiveHandle *AH);
index f08a0d3085fb591084a89e02d75693f239926a0d..3bc49e44358537a5602dc38f6f46d39a2fdb8cb9 100644 (file)
@@ -5,7 +5,7 @@
  *     Implements the basic DB functions used by the archiver.
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.23 2001/08/12 19:02:39 petere Exp $
+ *       $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.24 2001/08/22 20:23:23 petere Exp $
  *
  * NOTES
  *
@@ -40,7 +40,7 @@
 static const char *modulename = gettext_noop("archiver (db)");
 
 static void _check_database_version(ArchiveHandle *AH, bool ignoreVersion);
-static PGconn *_connectDB(ArchiveHandle *AH, const char *newdbname, char *newUser);
+static PGconn *_connectDB(ArchiveHandle *AH, const char *newdbname, const char *newUser);
 static int     _executeSqlCommand(ArchiveHandle *AH, PGconn *conn, PQExpBuffer qry, char *desc);
 static void notice_processor(void *arg, const char *message);
 
@@ -226,29 +226,44 @@ ConnectedUser(ArchiveHandle *AH)
 }
 
 /*
- * Reconnect the DB associated with the archive handle
+ * Reconnect to the server.  If dbname is not NULL, use that database,
+ * else the one associated with the archive handle.  If username is
+ * not NULL, use that user name, else the one from the handle.  If
+ * both the database and the user and match the existing connection
+ * already, nothing will be done.
+ *
+ * Returns 1 in any case.
  */
 int
-ReconnectDatabase(ArchiveHandle *AH, const char *newdbname, char *newUser)
+ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *username)
 {
        PGconn     *newConn;
-       char       *dbname;
+       const char *newdbname;
+       const char *newusername;
+
+       if (!dbname)
+               newdbname = PQdb(AH->connection);
+       else
+               newdbname = dbname;
 
-       if (!newdbname || (strcmp(newdbname, "-") == 0))
-               dbname = PQdb(AH->connection);
+       if (!username)
+               newusername = PQuser(AH->connection);
        else
-               dbname = (char *) newdbname;
+               newusername = username;
 
        /* Let's see if the request is already satisfied */
-       if (strcmp(PQuser(AH->connection), newUser) == 0 && strcmp(newdbname, PQdb(AH->connection)) == 0)
+       if (strcmp(newusername, PQuser(AH->connection)) == 0
+               && strcmp(newdbname, PQdb(AH->connection)) == 0)
                return 1;
 
-       newConn = _connectDB(AH, dbname, newUser);
+       newConn = _connectDB(AH, newdbname, newusername);
 
        PQfinish(AH->connection);
        AH->connection = newConn;
+
        free(AH->username);
-       AH->username = strdup(newUser);
+       AH->username = strdup(newusername);
+       /* XXX Why don't we update AH->dbname? */
 
        return 1;
 }
@@ -257,7 +272,7 @@ ReconnectDatabase(ArchiveHandle *AH, const char *newdbname, char *newUser)
  * Connect to the db again.
  */
 static PGconn *
-_connectDB(ArchiveHandle *AH, const char *reqdb, char *requser)
+_connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser)
 {
        int                     need_pass;
        PGconn     *newConn;
@@ -267,7 +282,7 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, char *requser)
        char       *newdb;
        char       *newuser;
 
-       if (!reqdb || (strcmp(reqdb, "-") == 0))
+       if (!reqdb)
                newdb = PQdb(AH->connection);
        else
                newdb = (char *) reqdb;
index 56067a34ee597d0a215f8cf414ca62dc4fcc4e94..f81439e2036e46619940262fb2b3cdaef9aa1627 100644 (file)
@@ -22,7 +22,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.223 2001/08/19 22:17:03 petere Exp $
+ *       $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.224 2001/08/22 20:23:23 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -167,6 +167,9 @@ help(const char *progname)
                "  -v, --verbose            verbose mode\n"
                "  -W, --password           force password prompt (should happen automatically)\n"
                "  -x, --no-privileges      do not dump privileges (grant/revoke)\n"
+               "  -X use-set-session-authorization, --use-set-session-authorization\n"
+               "                           output SET SESSION AUTHORIZATION commands rather\n"
+               "                           than \\connect commands\n"
                "  -Z, --compress {0-9}     compression level for compressed formats\n"
                ));
 #else
@@ -198,6 +201,9 @@ help(const char *progname)
                "  -v                       verbose mode\n"
                "  -W                       force password prompt (should happen automatically)\n"
                "  -x                       do not dump privileges (grant/revoke)\n"
+               "  -X use-set-session-authorization\n"
+               "                           output SET SESSION AUTHORIZATION commands rather\n"
+               "                           than \\connect commands\n"
                "  -Z {0-9}                 compression level for compressed formats\n"
                ));
 #endif
@@ -628,6 +634,7 @@ main(int argc, char **argv)
        int                     outputBlobs = 0;
        int                     outputNoOwner = 0;
        int                     outputNoReconnect = 0;
+       static int      use_setsessauth = 0;
        char       *outputSuperuser = NULL;
 
        RestoreOptions *ropt;
@@ -661,7 +668,11 @@ main(int argc, char **argv)
                {"no-acl", no_argument, NULL, 'x'},
                {"compress", required_argument, NULL, 'Z'},
                {"help", no_argument, NULL, '?'},
-               {"version", no_argument, NULL, 'V'}
+               {"version", no_argument, NULL, 'V'},
+
+               /* the following options don't have an equivalent short option
+           letter, but are available as '-X long-name' */
+               {"use-set-session-authorization", no_argument, &use_setsessauth, 1}
        };
        int                     optindex;
 
@@ -709,9 +720,9 @@ main(int argc, char **argv)
        }
 
 #ifdef HAVE_GETOPT_LONG
-       while ((c = getopt_long(argc, argv, "abcCdDf:F:h:inNoOp:RsS:t:uU:vWxzZ:V?", long_options, &optindex)) != -1)
+       while ((c = getopt_long(argc, argv, "abcCdDf:F:h:inNoOp:RsS:t:uU:vWxX:zZ:V?", long_options, &optindex)) != -1)
 #else
-       while ((c = getopt(argc, argv, "abcCdDf:F:h:inNoOp:RsS:t:uU:vWxzZ:V?-")) != -1)
+       while ((c = getopt(argc, argv, "abcCdDf:F:h:inNoOp:RsS:t:uU:vWxX:zZ:V?-")) != -1)
 #endif
 
        {
@@ -851,6 +862,26 @@ main(int argc, char **argv)
                                aclsSkip = true;
                                break;
 
+                               /*
+                                * Option letters were getting scarce, so I invented
+                                * this new scheme: '-X feature' turns on some
+                                * feature.  Compare to the -f option in GCC.  You
+                                * should also add an equivalent GNU-style option
+                                * --feature.  Features that require arguments should
+                                * use '-X feature=foo'.
+                                */
+                       case 'X':
+                               if (strcmp(optarg, "use-set-session-authorization")==0)
+                                       use_setsessauth = 1;
+                               else
+                               {
+                                       fprintf(stderr,
+                                                       gettext("%s: invalid -X option -- %s\n"),
+                                                       progname, optarg);
+                                       fprintf(stderr, gettext("Try '%s --help' for more information.\n"), progname);
+                                       exit(1);
+                               }
+                               break;
                        case 'Z':                       /* Compression Level */
                                compressLevel = atoi(optarg);
                                break;
@@ -863,6 +894,10 @@ main(int argc, char **argv)
                                                progname);
                                exit(1);
                                break;
+#else
+                               /* This covers the long options equivalent to -X xxx. */
+                       case 0:
+                               break;
 #endif
                        default:
                                fprintf(stderr, gettext("Try '%s --help' for more information.\n"), progname);
@@ -1040,6 +1075,7 @@ main(int argc, char **argv)
                ropt->create = outputCreate;
                ropt->noOwner = outputNoOwner;
                ropt->noReconnect = outputNoReconnect;
+               ropt->use_setsessauth = use_setsessauth;
 
                if (outputSuperuser)
                        ropt->superuser = outputSuperuser;
index 4580f268b0288af3e68ae3c659d2befd6daed634..aff3bc7ea00aaae19cd3a1d6cbc5219c443f95e6 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_dump.h,v 1.69 2001/08/10 18:57:38 tgl Exp $
+ * $Id: pg_dump.h,v 1.70 2001/08/22 20:23:23 petere Exp $
  *
  * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
  *
@@ -193,7 +193,7 @@ typedef struct _oprInfo
 } OprInfo;
 
 /* global decls */
-extern bool g_force_quotes;            /* double-quotes for identifiers flag */
+extern bool force_quotes;              /* double-quotes for identifiers flag */
 extern bool g_verbose;                 /* verbose flag */
 extern Oid     g_last_builtin_oid; /* value of the last builtin oid */
 extern Archive *g_fout;                        /* the script file */
index 3ba07e848b2bf421fe38aeee6c416dde5f4f2119..0bff04903cb0e9fc6f4239159bd57ab475c5031f 100644 (file)
@@ -34,7 +34,7 @@
  *
  *
  * IDENTIFICATION
- *             $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_restore.c,v 1.24 2001/08/19 22:17:03 petere Exp $
+ *             $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_restore.c,v 1.25 2001/08/22 20:23:24 petere Exp $
  *
  * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
  *
@@ -81,39 +81,6 @@ static char *_cleanupName(char *name);
 
 typedef struct option optType;
 
-#ifdef HAVE_GETOPT_LONG
-struct option cmdopts[] = {
-       {"clean", 0, NULL, 'c'},
-       {"create", 0, NULL, 'C'},
-       {"data-only", 0, NULL, 'a'},
-       {"dbname", 1, NULL, 'd'},
-       {"file", 1, NULL, 'f'},
-       {"format", 1, NULL, 'F'},
-       {"function", 1, NULL, 'P'},
-       {"host", 1, NULL, 'h'},
-       {"ignore-version", 0, NULL, 'i'},
-       {"index", 1, NULL, 'I'},
-       {"list", 0, NULL, 'l'},
-       {"no-privileges", 0, NULL, 'x'},
-       {"no-acl", 0, NULL, 'x'},
-       {"no-owner", 0, NULL, 'O'},
-       {"no-reconnect", 0, NULL, 'R'},
-       {"port", 1, NULL, 'p'},
-       {"oid-order", 0, NULL, 'o'},
-       {"orig-order", 0, NULL, 'N'},
-       {"password", 0, NULL, 'W'},
-       {"rearrange", 0, NULL, 'r'},
-       {"schema-only", 0, NULL, 's'},
-       {"superuser", 1, NULL, 'S'},
-       {"table", 1, NULL, 't'},
-       {"trigger", 1, NULL, 'T'},
-       {"use-list", 1, NULL, 'L'},
-       {"username", 1, NULL, 'U'},
-       {"verbose", 0, NULL, 'v'},
-       {NULL, 0, NULL, 0}
-};
-
-#endif
 
 int
 main(int argc, char **argv)
@@ -124,6 +91,45 @@ main(int argc, char **argv)
        char       *fileSpec = NULL;
        extern int      optind;
        extern char *optarg;
+       static int      use_setsessauth = 0;
+
+#ifdef HAVE_GETOPT_LONG
+       struct option cmdopts[] = {
+               {"clean", 0, NULL, 'c'},
+               {"create", 0, NULL, 'C'},
+               {"data-only", 0, NULL, 'a'},
+               {"dbname", 1, NULL, 'd'},
+               {"file", 1, NULL, 'f'},
+               {"format", 1, NULL, 'F'},
+               {"function", 1, NULL, 'P'},
+               {"host", 1, NULL, 'h'},
+               {"ignore-version", 0, NULL, 'i'},
+               {"index", 1, NULL, 'I'},
+               {"list", 0, NULL, 'l'},
+               {"no-privileges", 0, NULL, 'x'},
+               {"no-acl", 0, NULL, 'x'},
+               {"no-owner", 0, NULL, 'O'},
+               {"no-reconnect", 0, NULL, 'R'},
+               {"port", 1, NULL, 'p'},
+               {"oid-order", 0, NULL, 'o'},
+               {"orig-order", 0, NULL, 'N'},
+               {"password", 0, NULL, 'W'},
+               {"rearrange", 0, NULL, 'r'},
+               {"schema-only", 0, NULL, 's'},
+               {"superuser", 1, NULL, 'S'},
+               {"table", 1, NULL, 't'},
+               {"trigger", 1, NULL, 'T'},
+               {"use-list", 1, NULL, 'L'},
+               {"username", 1, NULL, 'U'},
+               {"verbose", 0, NULL, 'v'},
+
+               /* the following options don't have an equivalent short option
+                  letter, but are available as '-X long-name' */
+               {"use-set-session-authorization", no_argument, &use_setsessauth, 1},
+               {NULL, 0, NULL, 0}
+       };
+#endif /* HAVE_GETOPT_LONG */
+
 
 #ifdef ENABLE_NLS
        setlocale(LC_ALL, "");
@@ -153,9 +159,9 @@ main(int argc, char **argv)
        }
 
 #ifdef HAVE_GETOPT_LONG
-       while ((c = getopt_long(argc, argv, "acCd:f:F:h:i:lL:NoOp:P:rRsS:t:T:uU:vWx", cmdopts, NULL)) != EOF)
+       while ((c = getopt_long(argc, argv, "acCd:f:F:h:i:lL:NoOp:P:rRsS:t:T:uU:vWxX:", cmdopts, NULL)) != EOF)
 #else
-       while ((c = getopt(argc, argv, "acCd:f:F:h:i:lL:NoOp:P:rRsS:t:T:uU:vWx")) != -1)
+       while ((c = getopt(argc, argv, "acCd:f:F:h:i:lL:NoOp:P:rRsS:t:T:uU:vWxX:")) != -1)
 #endif
        {
                switch (c)
@@ -267,6 +273,26 @@ main(int argc, char **argv)
                        case 'x':                       /* skip ACL dump */
                                opts->aclsSkip = 1;
                                break;
+
+                       case 'X':
+                               if (strcmp(optarg, "use-set-session-authorization")==0)
+                                       use_setsessauth = 1;
+                               else
+                               {
+                                       fprintf(stderr,
+                                                       gettext("%s: invalid -X option -- %s\n"),
+                                                       progname, optarg);
+                                       fprintf(stderr, gettext("Try '%s --help' for more information.\n"), progname);
+                                       exit(1);
+                               }
+                               break;
+
+#ifdef HAVE_GETOPT_LONG
+                               /* This covers the long options equivalent to -X xxx. */
+                       case 0:
+                               break;
+#endif
+
                        default:
                                fprintf(stderr, gettext("Try '%s --help' for more information.\n"), progname);
                                exit(1);
@@ -278,6 +304,8 @@ main(int argc, char **argv)
        else
                fileSpec = NULL;
 
+       opts->use_setsessauth = use_setsessauth;
+
        if (opts->formatName)
        {
 
@@ -381,6 +409,9 @@ usage(const char *progname)
                "  -v, --verbose            verbose mode\n"
                "  -W, --password           force password prompt (should happen automatically)\n"
                "  -x, --no-privileges      skip restoration of access privileges (grant/revoke)\n"
+               "  -X use-set-session-authorization, --use-set-session-authorization\n"
+               "                           use SET SESSION AUTHORIZATION commands instead\n"
+               "                           of reconnecting, if possible\n"
                ));
 
 #else /* not HAVE_GETOPT_LONG */
@@ -414,6 +445,9 @@ usage(const char *progname)
                "  -v                       verbose mode\n"
                "  -W                       force password prompt (should happen automatically)\n"
                "  -x                       skip restoration of access privileges (grant/revoke)\n"
+               "  -X use-set-session-authorization\n"
+               "                           use SET SESSION AUTHORIZATION commands instead\n"
+               "                           of reconnecting, if possible\n"
                ));
 #endif
        puts(gettext("If no input file name is supplied, then standard input is used.\n"));