diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 80dd35041f..73ab39cef1 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -1,5 +1,5 @@ @@ -318,16 +318,16 @@ PostgreSQL documentation - 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 . Note that - does not prevent all reconnections to the - database, only the ones that are exclusively used for - ownership adjustments. + Do not output commands to set + ownership of objects to match the original database. + By default, pg_dump issues + SET SESSION AUTHORIZATION + statements to set ownership of created schema elements. + These statements + will fail when the script is run unless it is started by a superuser + (or the same user that owns all of the objects in the script). + To make a script that can be restored by any user, but will give + that user ownership of all the objects, specify @@ -343,27 +343,8 @@ PostgreSQL documentation - 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 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 may specify the option when you - call pg_restore. + This option is obsolete but still accepted for backwards + compatibility. @@ -385,8 +366,7 @@ PostgreSQL documentation Specify the superuser user name to use when disabling triggers. This is only relevant if @@ -444,32 +424,10 @@ PostgreSQL documentation - 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 - psql \connect command. - This command actually opens a new connection, which might - require manual interaction (e.g., passwords). If you use the - option, then - pg_dump will instead output 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 psql, 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 may specify the option when you - call pg_restore. + This option is obsolete but still accepted for backwards + compatibility. + pg_dump now always behaves in the + way formerly selected by this option. @@ -490,10 +448,8 @@ PostgreSQL documentation Presently, the commands emitted for diff --git a/doc/src/sgml/ref/pg_restore.sgml b/doc/src/sgml/ref/pg_restore.sgml index 1600925af8..88319e2e34 100644 --- a/doc/src/sgml/ref/pg_restore.sgml +++ b/doc/src/sgml/ref/pg_restore.sgml @@ -1,4 +1,4 @@ - + @@ -261,10 +261,16 @@ - Prevent any attempt to restore original object - ownership. Objects will be owned by the user name used to - attach to the database. See also under and - . + Do not output commands to set + ownership of objects to match the original database. + By default, pg_restore issues + SET SESSION AUTHORIZATION + statements to set ownership of created schema elements. + These statements will fail unless the initial connection to the + database is made by a superuser + (or the same user that owns all of the objects in the script). + With , any user name can be used for the + initial connection, and this user will own all the created objects. @@ -311,20 +317,8 @@ - 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 undesirable (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 \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. + This option is obsolete but still accepted for backwards + compatibility. @@ -397,16 +391,10 @@ - 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 opened, - which might require manual interaction (e.g., passwords). If - you use the option, - then pg_restore will instead use the 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. + This option is obsolete but still accepted for backwards + compatibility. + pg_restore now always behaves in the + way formerly selected by this option. @@ -428,8 +416,7 @@ Presently, the commands emitted for diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h index 5bcb1b2622..8e91a6b1f8 100644 --- a/src/bin/pg_dump/pg_backup.h +++ b/src/bin/pg_dump/pg_backup.h @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup.h,v 1.25 2003/08/28 20:21:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup.h,v 1.26 2003/09/23 22:48:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -62,12 +62,7 @@ typedef int (*DataDumperPtr) (Archive *AH, char *oid, void *userArg); typedef struct _restoreOptions { int create; /* Issue commands to create the database */ - int noOwner; /* Don't reconnect to database to match - * original object owner */ - int noReconnect; /* Don't reconnect to database under any - * cirsumstances */ - int use_setsessauth;/* use SET SESSSION AUTHORIZATION instead - * of \connect */ + int noOwner; /* Don't try to match original object owner */ int disable_triggers; /* disable triggers during * data-only restore */ char *superuser; /* Username to use as superuser */ diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index 6e5914c96e..cf39972457 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.75 2003/08/28 20:21:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.76 2003/09/23 22:48:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -49,8 +49,9 @@ static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt, static int _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData); static void _doSetSessionAuth(ArchiveHandle *AH, const char *user); -static void _reconnectAsOwner(ArchiveHandle *AH, const char *dbname, TocEntry *te); -static void _reconnectAsUser(ArchiveHandle *AH, const char *dbname, const char *user); +static void _reconnectToDB(ArchiveHandle *AH, const char *dbname, const char *user); +static void _becomeUser(ArchiveHandle *AH, const char *user); +static void _becomeOwner(ArchiveHandle *AH, TocEntry *te); static void _selectOutputSchema(ArchiveHandle *AH, const char *schemaName); static teReqs _tocEntryRequired(TocEntry *te, RestoreOptions *ropt); @@ -144,10 +145,6 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt) * initially connected to, not the one we will create, which is very * bad... */ - - if (ropt->create && ropt->noReconnect) - die_horribly(AH, modulename, "-C and -R are incompatible options\n"); - if (ropt->create && ropt->dropSchema) die_horribly(AH, modulename, "-C and -c are incompatible options\n"); @@ -221,7 +218,7 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt) /* We want the schema */ ahlog(AH, 1, "dropping %s %s\n", te->desc, te->tag); /* Select owner and schema as necessary */ - _reconnectAsOwner(AH, NULL, te); + _becomeOwner(AH, te); _selectOutputSchema(AH, te->namespace); /* Drop it */ ahprintf(AH, "%s", te->dropStmt); @@ -260,7 +257,7 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt) if (strcmp(te->desc, "DATABASE") == 0) { ahlog(AH, 1, "connecting to new database \"%s\" as user \"%s\"\n", te->tag, te->owner); - _reconnectAsUser(AH, te->tag, te->owner); + _reconnectToDB(AH, te->tag, te->owner); } } @@ -310,11 +307,8 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt) { _disableTriggersIfNecessary(AH, te, ropt); - /* - * Reconnect if necessary (_disableTriggers may - * have reconnected) - */ - _reconnectAsOwner(AH, NULL, te); + /* Select owner and schema as necessary */ + _becomeOwner(AH, te); _selectOutputSchema(AH, te->namespace); ahlog(AH, 1, "restoring data for table \"%s\"\n", te->tag); @@ -347,7 +341,7 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt) } } te = te->next; - } + } /* end loop over TOC entries */ /* * Now use blobs_xref (if used) to fixup any refs for tables that we @@ -439,9 +433,6 @@ _canRestoreBlobs(ArchiveHandle *AH) static void _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt) { - char *oldUser; - char *oldSchema; - /* This hack is only needed in a data-only restore */ if (!ropt->dataOnly || !ropt->disable_triggers) return; @@ -450,23 +441,12 @@ _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *rop if (te && strcmp(te->desc, "BLOBS") == 0) return; - oldUser = strdup(AH->currUser); - oldSchema = strdup(AH->currSchema); - /* * Become superuser if possible, since they are the only ones who can - * update pg_class. If -S was not given, but we are allowed to use - * SET SESSION AUTHORIZATION, assume the initial user identity is a - * superuser. Otherwise we just have to bull ahead anyway. + * update pg_class. If -S was not given, assume the initial user identity + * is a superuser. */ - if (ropt->superuser) - { - _reconnectAsUser(AH, NULL, ropt->superuser); - /* be careful to preserve schema setting */ - _selectOutputSchema(AH, oldSchema); - } - else if (AH->ropt->use_setsessauth) - _doSetSessionAuth(AH, NULL); + _becomeUser(AH, ropt->superuser); ahlog(AH, 1, "disabling triggers\n"); @@ -487,28 +467,11 @@ _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *rop else ahprintf(AH, "UPDATE pg_catalog.pg_class SET reltriggers = 0 FROM pg_catalog.pg_namespace " "WHERE relnamespace = pg_namespace.oid AND nspname !~ '^pg_';\n\n"); - - /* - * Restore original user and schema state. - */ - if (ropt->superuser) - { - _reconnectAsUser(AH, NULL, oldUser); - /* be careful to preserve schema setting */ - _selectOutputSchema(AH, oldSchema); - } - else if (AH->ropt->use_setsessauth) - _doSetSessionAuth(AH, oldUser); - free(oldUser); - free(oldSchema); } static void _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt) { - char *oldUser; - char *oldSchema; - /* This hack is only needed in a data-only restore */ if (!ropt->dataOnly || !ropt->disable_triggers) return; @@ -517,23 +480,12 @@ _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt if (te && strcmp(te->desc, "BLOBS") == 0) return; - oldUser = strdup(AH->currUser); - oldSchema = strdup(AH->currSchema); - /* * Become superuser if possible, since they are the only ones who can - * update pg_class. If -S was not given, but we are allowed to use - * SET SESSION AUTHORIZATION, assume the initial user identity is a - * superuser. Otherwise we just have to bull ahead anyway. + * update pg_class. If -S was not given, assume the initial user identity + * is a superuser. */ - if (ropt->superuser) - { - _reconnectAsUser(AH, NULL, ropt->superuser); - /* be careful to preserve schema setting */ - _selectOutputSchema(AH, oldSchema); - } - else if (AH->ropt->use_setsessauth) - _doSetSessionAuth(AH, NULL); + _becomeUser(AH, ropt->superuser); ahlog(AH, 1, "enabling triggers\n"); @@ -557,20 +509,6 @@ _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt "(SELECT pg_catalog.count(*) FROM pg_catalog.pg_trigger where pg_class.oid = tgrelid) " "FROM pg_catalog.pg_namespace " "WHERE relnamespace = pg_namespace.oid AND nspname !~ '^pg_';\n\n"); - - /* - * Restore original user and schema state. - */ - if (ropt->superuser) - { - _reconnectAsUser(AH, NULL, oldUser); - /* be careful to preserve schema setting */ - _selectOutputSchema(AH, oldSchema); - } - else if (AH->ropt->use_setsessauth) - _doSetSessionAuth(AH, oldUser); - free(oldUser); - free(oldSchema); } /* @@ -2087,8 +2025,8 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt) /* * Issue a SET SESSION AUTHORIZATION command. Caller is responsible - * for updating state if appropriate. If user is NULL, the - * specification DEFAULT will be used. + * for updating state if appropriate. If user is NULL or an empty string, + * the specification DEFAULT will be used. */ static void _doSetSessionAuth(ArchiveHandle *AH, const char *user) @@ -2096,11 +2034,11 @@ _doSetSessionAuth(ArchiveHandle *AH, const char *user) PQExpBuffer cmd = createPQExpBuffer(); appendPQExpBuffer(cmd, "SET SESSION AUTHORIZATION "); - if (user) - /* - * SQL requires a string literal here. Might as well be correct. - */ + /* + * SQL requires a string literal here. Might as well be correct. + */ + if (user && *user) appendStringLiteral(cmd, user, false); else appendPQExpBuffer(cmd, "DEFAULT"); @@ -2126,34 +2064,17 @@ _doSetSessionAuth(ArchiveHandle *AH, const char *user) /* - * 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. + * Issue the commands to connect to the specified database + * as the specified user. * * If we're currently restoring right into a database, this will * actually establish a connection. Otherwise it puts a \connect into * the script output. */ static void -_reconnectAsUser(ArchiveHandle *AH, const char *dbname, const char *user) +_reconnectToDB(ArchiveHandle *AH, const char *dbname, const char *user) { - if (!user || strlen(user) == 0 - || (strcmp(AH->currUser, user) == 0 && !dbname)) - return; /* no need to do anything */ - - /* - * Use SET SESSION AUTHORIZATION if allowed and no database change - * needed - */ - if (!dbname && AH->ropt->use_setsessauth) - _doSetSessionAuth(AH, user); - else if (AH->ropt && AH->ropt->noReconnect) - { - /* When -R was given, don't do anything. */ - return; - } - else if (RestoringToDB(AH)) + if (RestoringToDB(AH)) ReconnectToServer(AH, dbname, user); else { @@ -2167,11 +2088,6 @@ _reconnectAsUser(ArchiveHandle *AH, const char *dbname, const char *user) ahprintf(AH, qry->data); destroyPQExpBuffer(qry); - - /* don't assume we still know the output schema */ - if (AH->currSchema) - free(AH->currSchema); - AH->currSchema = strdup(""); } /* @@ -2182,21 +2098,50 @@ _reconnectAsUser(ArchiveHandle *AH, const char *dbname, const char *user) free(AH->currUser); AH->currUser = strdup(user); + + /* don't assume we still know the output schema */ + if (AH->currSchema) + free(AH->currSchema); + AH->currSchema = strdup(""); +} + +/* + * Become the specified user, and update state to avoid redundant commands + * + * NULL or empty argument is taken to mean restoring the session default + */ +static void +_becomeUser(ArchiveHandle *AH, const char *user) +{ + if (!user) + user = ""; /* avoid null pointers */ + + if (AH->currUser && strcmp(AH->currUser, user) == 0) + return; /* no need to do anything */ + + _doSetSessionAuth(AH, 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 + * Become 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) +_becomeOwner(ArchiveHandle *AH, TocEntry *te) { if (AH->ropt && AH->ropt->noOwner) return; - _reconnectAsUser(AH, dbname, te->owner); + _becomeUser(AH, te->owner); } @@ -2250,7 +2195,7 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat char *pfx; /* Select owner and schema as necessary */ - _reconnectAsOwner(AH, NULL, te); + _becomeOwner(AH, te); _selectOutputSchema(AH, te->namespace); if (isData) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 010e6753ed..501cf59f1e 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -12,7 +12,7 @@ * by PostgreSQL * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.348 2003/09/22 00:23:34 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.349 2003/09/23 22:48:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -174,7 +174,6 @@ main(int argc, char **argv) int outputCreate = 0; int outputBlobs = 0; int outputNoOwner = 0; - int outputNoReconnect = 0; static int use_setsessauth = 0; static int disable_triggers = 0; char *outputSuperuser = NULL; @@ -322,8 +321,8 @@ main(int argc, char **argv) pgport = optarg; break; - case 'R': /* No reconnect */ - outputNoReconnect = 1; + case 'R': + /* no-op, still accepted for backwards compatibility */ break; case 's': /* dump schema only */ @@ -369,7 +368,7 @@ main(int argc, char **argv) */ case 'X': if (strcmp(optarg, "use-set-session-authorization") == 0) - use_setsessauth = 1; + /* no-op, still allowed for compatibility */ ; else if (strcmp(optarg, "disable-triggers") == 0) disable_triggers = 1; else @@ -585,8 +584,6 @@ main(int argc, char **argv) ropt->superuser = outputSuperuser; ropt->create = outputCreate; ropt->noOwner = outputNoOwner; - ropt->noReconnect = outputNoReconnect; - ropt->use_setsessauth = use_setsessauth; ropt->disable_triggers = disable_triggers; if (compressLevel == -1) @@ -633,18 +630,13 @@ help(const char *progname) printf(_(" -D, --column-inserts dump data as INSERT commands with column names\n")); printf(_(" -n, --schema=SCHEMA dump the named schema only\n")); printf(_(" -o, --oids include OIDs in dump\n")); - printf(_(" -O, --no-owner do not output \\connect commands in plain\n" - " text format\n")); - printf(_(" -R, --no-reconnect disable ALL reconnections to the database in\n" - " plain text format\n")); + printf(_(" -O, --no-owner do not output commands to set object ownership\n" + " in plain text format\n")); printf(_(" -s, --schema-only dump only the schema, no data\n")); printf(_(" -S, --superuser=NAME specify the superuser user name to use in\n" " plain text format\n")); printf(_(" -t, --table=TABLE dump the named table only\n")); printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n")); - printf(_(" -X use-set-session-authorization, --use-set-session-authorization\n" - " output SET SESSION AUTHORIZATION commands rather\n" - " than \\connect commands\n")); printf(_(" -X disable-triggers, --disable-triggers\n" " disable triggers during data-only restore\n")); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index 8c83254c81..e0853690f8 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.27 2003/08/07 21:11:58 tgl Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.28 2003/09/23 22:48:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -659,8 +659,7 @@ runPgDump(const char *dbname) const char *p; int ret; - appendPQExpBuffer(cmd, "%s %s -X use-set-session-authorization -Fp '", - pgdumploc, pgdumpopts->data); + appendPQExpBuffer(cmd, "%s %s -Fp '", pgdumploc, pgdumpopts->data); /* Shell quoting is not quite like SQL quoting, so can't use fmtId */ for (p = dbname; *p; p++) diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c index e2726b8817..2414de8f5c 100644 --- a/src/bin/pg_dump/pg_restore.c +++ b/src/bin/pg_dump/pg_restore.c @@ -34,7 +34,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_restore.c,v 1.51 2003/08/28 20:21:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_restore.c,v 1.52 2003/09/23 22:48:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -209,7 +209,7 @@ main(int argc, char **argv) opts->rearrange = 1; break; case 'R': - opts->noReconnect = 1; + /* no-op, still accepted for backwards compatibility */ break; case 'P': /* Function */ opts->selTypes = 1; @@ -262,7 +262,7 @@ main(int argc, char **argv) case 'X': if (strcmp(optarg, "use-set-session-authorization") == 0) - use_setsessauth = 1; + /* no-op, still allowed for compatibility */ ; else if (strcmp(optarg, "disable-triggers") == 0) disable_triggers = 1; else @@ -290,7 +290,6 @@ main(int argc, char **argv) else fileSpec = NULL; - opts->use_setsessauth = use_setsessauth; opts->disable_triggers = disable_triggers; if (opts->formatName) @@ -378,21 +377,16 @@ usage(const char *progname) " output from this file\n")); printf(_(" -N, --orig-order restore in original dump order\n")); printf(_(" -o, --oid-order restore in OID order\n")); - printf(_(" -O, --no-owner do not reconnect to database to match\n" - " object owner\n")); + printf(_(" -O, --no-owner do not output commands to set object ownership\n")); printf(_(" -P, --function=NAME(args)\n" " restore named function\n")); printf(_(" -r, --rearrange rearrange output to put indexes etc. at end\n")); - printf(_(" -R, --no-reconnect disallow ALL reconnections to the database\n")); printf(_(" -s, --schema-only restore only the schema, no data\n")); printf(_(" -S, --superuser=NAME specify the superuser user name to use for\n" " disabling triggers\n")); printf(_(" -t, --table=NAME restore named table\n")); printf(_(" -T, --trigger=NAME restore named trigger\n")); printf(_(" -x, --no-privileges skip restoration of access privileges (grant/revoke)\n")); - printf(_(" -X use-set-session-authorization, --use-set-session-authorization\n" - " use SET SESSION AUTHORIZATION commands instead\n" - " of reconnecting, if possible\n")); printf(_(" -X disable-triggers, --disable-triggers\n" " disable triggers during data-only restore\n"));