Add option to output SET SESSION AUTHORIZATION commands rather than
authorPeter Eisentraut
Wed, 22 Aug 2001 20:23:24 +0000 (20:23 +0000)
committerPeter Eisentraut
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 @@
 
 
@@ -43,6 +43,7 @@ Postgres documentation
    -t table
    -v
    -x
+   -X keyword
    -Z 0...9
    -h host
    -p port
@@ -59,44 +60,56 @@ Postgres documentation
   
 
   
-   pg_dump is a utility for dumping out a 
-   Postgres 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 
-    to rebuild the database, but also
-   allow pg_restore 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.
+   pg_dump is a utility for saving a
+   PostgreSQL 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  to rebuild the database,
+   and they also allow pg_restore 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.
   
 
   
-   pg_dump 
-   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.
+   pg_dump 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.
   
 
   
    pg_dump 
    is useful for dumping out the contents of a database to move from one
-   Postgres installation to another.  After running 
-   pg_dump,
-   one should examine the output for any warnings, especially
-   in light of the limitations listed below. 
+   Postgres installation to another.
   
 
   
-   When used with one of the alternate file formats and combined with 
-   pg_restore, it provides a flexible archival 
-   and transfer mechanism. pg_dump can be used 
-   to backup an entire database, then pg_restore 
-   can be used to examine the archive and/or select which parts of the 
-   database are to be restored.
-   See the  documentation for details.
+   When used with one of the archive file formats and combined with
+   pg_restore, it provides a flexible archival and
+   transfer mechanism. pg_dump can be used to
+   backup an entire database, then pg_restore can
+   be used to examine the archive and/or select which parts of the
+   database are to be restored.  See the 
+   linkend="app-pgrestore"> documentation for details.
+  
+
+  
+   While running pg_dump, one should examine the
+   output for any warnings (printed on standard error), especially in
+   light of the limitations listed below.
+  
+
+  
+   pg_dump makes consistent backups even if the
+   database is being used concurrently.  pg_dump
+   does not block other users accessing the database (readers or
+   writers).
   
 
   
@@ -141,7 +154,7 @@ Postgres documentation
       --clean
       
        
-        Dump commands to clean (drop) the schema prior to (the
+        Output commands to clean (drop) the schema prior to (the
         commands for) creating it.
        
       
@@ -162,9 +175,10 @@ Postgres documentation
       --inserts
       
        
-   Dump data as proper INSERT commands (not
-   COPY). This will make restoration very
-   slow.
+   Dump data as proper INSERT commands (rather
+   than COPY). This will make restoration very
+   slow, but it makes the archives more portable to other RDBMS
+   packages.
        
       
      
@@ -189,7 +203,8 @@ Postgres documentation
       --file=file
       
        
-   Send output to the specified file.
+   Send output to the specified file.  If this is omitted, the
+   standard output is used.
        
       
      
@@ -199,7 +214,8 @@ Postgres documentation
       --format=format
       
        
-   Format can be one of the following:
+        Selects the format of the output.
+   format can be one of the following:
 
        
         
@@ -289,7 +305,10 @@ Postgres documentation
       --oids
       
        
-   Dump object identifiers (OIDs) for every table.
+   Dump object identifiers (OIDs) 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.
        
       
      
@@ -299,11 +318,22 @@ Postgres documentation
       --no-owner
       
        
-   In plain text output mode, do not set object ownership to
-        match the original database. Typically,
-        pg_dump issues
-        (psql-specific) \connect
-        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,
+   pg_dump issues
+   (psql-specific) \connect
+   statements to set ownership of schema elements.  See also
+   under  and 
+   use-set-session-authorization.  Note that
+    does not prevent all reconnections to the
+   database, only the ones that are exclusively used for
+   ownership adjustments.
+       
+
+       
+        This option is only meaningful for the plain text format.  For
+        the other formats, you need to specify the option when you
+        call pg_restore.
        
       
      
@@ -313,8 +343,27 @@ Postgres documentation
       --no-reconnect
       
        
-   In plain text output mode, prohibit pg_dump 
-        from issuing any \connect statements.
+   In plain text output mode, prohibit pg_dump
+        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
+        pg_dump lose this ownership information,
+        unless you use the 
+        use-set-session-authorization option.
+       
+
+       
+        One possible reason why reconnections during restore might not
+        be desired is if the access to the database requires manual
+        interaction (e.g., passwords).
+       
+
+       
+        This option is only meaningful for the plain text format.  For
+        the other formats, you need to specify the option when you
+        call pg_restore.
        
       
      
@@ -334,8 +383,10 @@ Postgres documentation
       --superuser=username
       
        
-   Specify the superuser user name to use when disabling triggers and/or 
-      setting ownership of schema elements.
+        The scripts or archives created by pg_dump
+        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.
        
       
      
@@ -366,8 +417,42 @@ Postgres documentation
       --no-acl
       
        
-   Prevent dumping of access privileges (grant/revoke commands)
-   and table ownership information.
+   Prevent dumping of access privileges (grant/revoke commands).
+       
+      
+     
+
+     
+      -X use-set-session-authorization
+      --use-set-session-authorization
+      
+       
+        Normally, if a (plain text mode) script generated by
+        pg_dump must alter the current database
+        user (e.g., to set correct object ownerships), it uses the
+         \connect command.
+        This command actually opens a new connection, which might
+        require manual interaction (e.g., passwords).  If you use the
+        , then
+        pg_dump will instead output 
+        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.
+       
+
+       
+        Since  is a
+        standard SQL command, whereas \connect only
+        works in , this option also enhances
+        the theoretical portability of the output script.
+       
+
+       
+        This option is only meaningful for the plain text format.  For
+        the other formats, you need to specify the option when you
+        call pg_restore.
        
       
      
@@ -442,7 +527,6 @@ Postgres documentation
 
  
 
-
  
   Diagnostics
 
@@ -551,6 +635,17 @@ connectDBStart() -- connect() failed: No such file or directory
 
  
 
+  History
+
+  
+   The pg_dump utility first appeared in
+   Postgres95 release 0.02.  The
+   non-plain-text output formats were introduced in
+   PostgreSQL 7.1.
+  
+
  
   See Also
 
index 0acb3fb1512503e970a7505c5ea354f1009b5f43..22f264ceac18a60a638c60519c9459def725f12e 100644 (file)
@@ -1,4 +1,4 @@
-
+
 
 
  
@@ -44,6 +44,7 @@
     -T  trigger 
     -v 
     -x 
+    -X keyword
     -h  host 
     -p  port 
     -U username 
 
   
    pg_restore is a utility for restoring a
-   Postgres database dumped by
-    in one of the non-plain-text formats.
+   Postgres database from an archive
+   created by  in one of the non-plain-text
+   formats.
   
 
   
-   The archive files, new with the 7.1 release, contain enough information for
-   pg_restore to rebuild the database, but also allow
-   pg_restore 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. pg_dump 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
+   pg_restore to rebuild the database, but also
+   allow pg_restore 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.
   
 
   
-   pg_restore 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
-   dump data as INSERTs option, pg_restore will not be able to
-   load the data using COPY statements.
+   pg_restore 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
+   pg_dump plain text format.  Some of the options
+   controlling the script output are therefore analogous to
+   pg_dump.
   
 
   
-   The most flexible output file format is the custom format (). It allows for
-   selection and reordering of all archived items, and is compressed by default. The tar
-   format () is not compressed and it is not possible to reorder
-   data when loading, but it is otherwise quite flexible.
+   Obviously, pg_restore cannot restore information
+   that is not present in the archive file; for instance, if the
+   archive was made using the dump data as
+   INSERTs option,
+   pg_restore will not be able to load the data
+   using COPY statements.
   
 
   
-   To reorder the items, it is first necessary to dump the contents of the archive:
+   The most flexible output file format is the custom
+   format (). It allows for selection and
+   reordering of all archived items, and is compressed by default. The
+   tar format () is not
+   compressed and it is not possible to reorder data when loading, but
+   it is otherwise quite flexible.
+  
+
+  
+   To reorder the items, it is first necessary to dump the table of
+   contents of the archive:
 
 $ pg_restore archive.file -l > archive.list
 
       --no-reconnect
       
        
-     Prohibit pg_restore from issuing any \connect
-        statements or reconnecting to the database if directly connected.
+        While restoring an archive, pg_restore
+        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
+        pg_restore from issuing any reconnection
+        requests.  (A connection request while in plain text mode, not
+        connected to a database, is made by putting out a 
+        linkend="app-psql"> \connect command.)
+        However, this option is a rather blunt instrument because it
+        makes pg_restore lose all object ownership
+        information, unless you use the
+         option.
        
       
      
       
      
 
+     
+      -X use-set-session-authorization
+      --use-set-session-authorization
+      
+       
+        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 ,
+        then pg_restore will instead use the 
+        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.
+       
+      
+     
+
     
    
 
@@ -592,6 +640,14 @@ connectDBStart() -- connect() failed: No such file or directory
 
  
 
+  History
+
+  
+   The pg_restore utility first appeared in
+   PostgreSQL 7.1.
+  
 
  
   See Also
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 - [email protected]
  *
@@ -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 - [email protected]
  *
@@ -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 - [email protected]
  * -   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 - [email protected] - 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 - [email protected]
  *
@@ -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"));