diff --git a/src/bin/pg_dump/Makefile b/src/bin/pg_dump/Makefile
index 6bbef564c5f523a6e2e6af0444be170bb998b41a..4d5d8a5f498eeca73b4545d3557664108c4344bb 100644
--- a/src/bin/pg_dump/Makefile
+++ b/src/bin/pg_dump/Makefile
@@ -4,7 +4,7 @@
 #
 # Copyright (c) 1994, Regents of the University of California
 #
-# $Header: /cvsroot/pgsql/src/bin/pg_dump/Makefile,v 1.21 2000/07/24 06:24:26 pjw Exp $
+# $Header: /cvsroot/pgsql/src/bin/pg_dump/Makefile,v 1.22 2000/08/01 15:51:44 pjw Exp $
 #
 #-------------------------------------------------------------------------
 
diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h
index 6e37a7c01d6272c325dde3652b3ee5bcff5edb8f..8fceb26c8e24645bd2c010947e508f1d19b86157 100644
--- a/src/bin/pg_dump/pg_backup.h
+++ b/src/bin/pg_dump/pg_backup.h
@@ -20,6 +20,22 @@
  *
  *	Initial version. 
  *
+ *
+ * Modifications - 28-Jul-2000 - pjw@rhyme.com.au (1.45)
+ *
+ * 		Added --create, --no-owner, --superuser, --no-reconnect (pg_dump & pg_restore)
+ *		Added code to dump 'Create Schema' statement (pg_dump)
+ *		Don't bother to disable/enable triggers if we don't have a superuser (pg_restore)
+ *		Cleaned up code for reconnecting to database.
+ *		Force a reconnect as superuser before enabling/disabling triggers.
+ *
+ * Modifications - 31-Jul-2000 - pjw@rhyme.com.au (1.46, 1.47)
+ *		Added & Removed --throttle (pg_dump)
+ *		Fixed minor bug in language dumping code: expbuffres were not being reset.
+ *		Fixed version number initialization in _allocAH (pg_backup_archiver.c)
+ *		Added second connection when restoring BLOBs to allow temp. table to survive
+ *		(db reconnection causes temp tables to be lost).
+ *
  *-------------------------------------------------------------------------
  */
 
@@ -53,6 +69,10 @@ typedef struct _Archive {
 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 */
+	char		*superuser;		/* Username to use as superuser */
 	int			dataOnly;
 	int			dropSchema;
 	char		*filename;
@@ -84,9 +104,9 @@ typedef struct _restoreOptions {
 	int			ignoreVersion;
 	int			requirePassword;
 
-	int		*idWanted;
-	int		limitToList;
-	int		compression;
+	int			*idWanted;
+	int			limitToList;
+	int			compression;
 
 } RestoreOptions;
 
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index 071a066912d6edef902fcee617c9ea470ce3749f..fb799db71b28ae7a7d06c3f2e23b7d4a784350b6 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -18,7 +18,10 @@
  *
  * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
  *
- *	Initial version. 
+ *		Initial version. 
+ *
+ * Modifications - 31-Jul-2000 - pjw@rhyme.com.au (1.46, 1.47)
+ *		Fixed version number initialization in _allocAH (pg_backup_archiver.c)
  *
  *-------------------------------------------------------------------------
  */
@@ -43,7 +46,9 @@ static int		_tocSortCompareByIDNum(const void *p1, const void *p2);
 static ArchiveHandle* 	_allocAH(const char* FileSpec, const ArchiveFormat fmt, 
 				int compression, ArchiveMode mode);
 static int 		_printTocEntry(ArchiveHandle* AH, TocEntry* te, RestoreOptions *ropt);
-static void		_reconnectAsOwner(ArchiveHandle* AH, TocEntry* te);
+
+static void		_reconnectAsOwner(ArchiveHandle* AH, const char *dbname, TocEntry* te);
+static void		_reconnectAsUser(ArchiveHandle* AH, const char *dbname, char *user);
 
 static int		_tocEntryRequired(TocEntry* te, RestoreOptions *ropt);
 static void		_disableTriggers(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
@@ -58,7 +63,7 @@ static char	*progname = "Archiver";
 static void		_die_horribly(ArchiveHandle *AH, const char *fmt, va_list ap);
 
 static int 		_canRestoreBlobs(ArchiveHandle *AH);
-
+static int 		_restoringToDB(ArchiveHandle *AH);
 
 /*
  *  Wrapper functions.
@@ -110,6 +115,9 @@ void RestoreArchive(Archive* AHX, RestoreOptions *ropt)
 
 	AH->ropt = ropt;
 
+	if (ropt->create && ropt->noReconnect)
+		die_horribly(AH, "%s: --create and --no-reconnect are incompatible options\n",progname);
+
 	/*
 	 * If we're using a DB connection, then connect it.
 	 */
@@ -121,8 +129,25 @@ void RestoreArchive(Archive* AHX, RestoreOptions *ropt)
 
 		ConnectDatabase(AHX, ropt->dbname, ropt->pghost, ropt->pgport, 
 							ropt->requirePassword, ropt->ignoreVersion);
+
+		/*
+		 * If no superuser was specified then see if the current user will do...
+		 */
+		if (!ropt->superuser)
+		{
+			if (UserIsSuperuser(AH, ConnectedUser(AH)))
+				ropt->superuser = strdup(ConnectedUser(AH));
+		}
+
 	}
 
+	if (!ropt->superuser)
+		fprintf(stderr, "\n%s: ******** WARNING ******** \n"
+							"        Data restoration may fail since any defined triggers\n"
+							"        can not be disabled (no superuser username specified).\n"
+							"        This is only a problem for restoration into a database\n"
+							"        with triggers already defined.\n\n", progname);
+
 	/*
 	 *	Setup the output file if necessary.
 	 */
@@ -155,16 +180,20 @@ void RestoreArchive(Archive* AHX, RestoreOptions *ropt)
 		/* Work out what, if anything, we want from this entry */
 		reqs = _tocEntryRequired(te, ropt);
 
-		/* Reconnect if necessary */
-		if (reqs != 0)
-		{
-			_reconnectAsOwner(AH, te); 
-		}
-
 		if ( (reqs & 1) != 0) /* We want the schema */
 		{
+			/* Reconnect if necessary */
+			_reconnectAsOwner(AH, "-", te);
+
 			ahlog(AH, 1, "Creating %s %s\n", te->desc, te->name);
 			_printTocEntry(AH, te, ropt);
+
+			/* If we created a DB, connect to it... */
+			if (strcmp(te->desc,"DATABASE") == 0)
+			{
+				ahlog(AH, 1, "Connecting to new DB '%s' as %s\n",te->name, te->owner);
+				_reconnectAsUser(AH, te->name, te->owner);
+			}
 		}
 
 		/* 
@@ -176,8 +205,6 @@ void RestoreArchive(Archive* AHX, RestoreOptions *ropt)
 				die_horribly(AH, "%s: Unable to restore data from a compressed archive\n", progname);
 #endif
 
-			ahlog(AH, 1, "Restoring data for %s \n", te->name);
-
 			ahprintf(AH, "--\n-- Data for TOC Entry ID %d (OID %s) %s %s\n--\n\n",
 						te->id, te->oid, te->desc, te->name);
 
@@ -197,6 +224,10 @@ void RestoreArchive(Archive* AHX, RestoreOptions *ropt)
 
 				_disableTriggers(AH, te, ropt);
 
+				/* Reconnect if necessary (_disableTriggers may have reconnected) */
+				_reconnectAsOwner(AH, "-", te);
+
+				ahlog(AH, 1, "Restoring data for %s \n", te->name);
 
 				/* If we have a copy statement, use it. As of V1.3, these are separate 
 				 * to allow easy import from withing a database connection. Pre 1.3 
@@ -256,6 +287,12 @@ void RestoreArchive(Archive* AHX, RestoreOptions *ropt)
 	{
 		PQfinish(AH->connection);
 		AH->connection = NULL;
+
+		if (AH->blobConnection)
+		{
+			PQfinish(AH->blobConnection);
+			AH->blobConnection = NULL;
+		}
 	}
 }
 
@@ -274,19 +311,89 @@ RestoreOptions*		NewRestoreOptions(void)
 	return opts;
 }
 
-static int _canRestoreBlobs(ArchiveHandle *AH)
+static int _restoringToDB(ArchiveHandle *AH)
 {
 	return (AH->ropt->useDB && AH->connection);
 }
 
+static int _canRestoreBlobs(ArchiveHandle *AH)
+{
+	return _restoringToDB(AH);
+}
+
 static void _disableTriggers(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
 {
+	char	*oldUser = NULL;
+
+	/* Can't do much if we're connected & don't have a superuser */
+	if (_restoringToDB(AH) && !ropt->superuser)
+		return;
+
+	/*
+     * Reconnect as superuser if possible, since they are the only ones
+	 * who can update pg_class...
+	 */
+	if (ropt->superuser)
+	{
+		/* If we're not allowing changes for ownership, then remember the user
+		 * so we can change it back here. Otherwise, let _reconnectAsOwner
+		 * do what it has to do.
+		 */
+		if (ropt->noOwner)
+			oldUser = strdup(ConnectedUser(AH));
+		_reconnectAsUser(AH, "-", ropt->superuser);
+	}
+
+	ahlog(AH, 1, "Disabling triggers\n");
+
+	/*
+     * Disable them. This is a hack. Needs to be done via an appropriate 'SET'
+	 * command when one is available.
+	 */
     ahprintf(AH, "-- Disable triggers\n");
     ahprintf(AH, "UPDATE \"pg_class\" SET \"reltriggers\" = 0 WHERE \"relname\" !~ '^pg_';\n\n");
+
+	/*
+	 * Restore the user connection from the start of this procedure
+	 * if _reconnectAsOwner is disabled.
+	 */
+	if (ropt->noOwner && oldUser)
+	{
+		_reconnectAsUser(AH, "-", oldUser);
+		free(oldUser);
+	}
 }
 
 static void _enableTriggers(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
 {
+	char		*oldUser = NULL;
+
+	/* Can't do much if we're connected & don't have a superuser */
+	if (_restoringToDB(AH) && !ropt->superuser)
+		return;
+
+	/*
+	 * Reconnect as superuser if possible, since they are the only ones
+	 * who can update pg_class...
+	 */
+	if (ropt->superuser)
+	{
+		/* If we're not allowing changes for ownership, then remember the user
+		 * so we can change it back here. Otherwise, let _reconnectAsOwner
+		 * do what it has to do
+		 */
+		if (ropt->noOwner)
+			oldUser = strdup(ConnectedUser(AH));
+
+		_reconnectAsUser(AH, "-", ropt->superuser);
+	}
+
+	ahlog(AH, 1, "Enabling triggers\n");
+
+	/*
+	 * Enable them. This is a hack. Needs to be done via an appropriate 'SET'
+	 * command when one is available.
+	 */
     ahprintf(AH, "-- Enable triggers\n");
     ahprintf(AH, "BEGIN TRANSACTION;\n");
     ahprintf(AH, "CREATE TEMP TABLE \"tr\" (\"tmp_relname\" name, \"tmp_reltriggers\" smallint);\n");
@@ -298,8 +405,17 @@ static void _enableTriggers(ArchiveHandle *AH, TocEntry *te, RestoreOptions *rop
 	    "\"pg_class\".\"relname\" = TMP.\"tmp_relname\";\n");
     ahprintf(AH, "DROP TABLE \"tr\";\n");
     ahprintf(AH, "COMMIT TRANSACTION;\n\n");
-}
 
+	/*
+	 * Restore the user connection from the start of this procedure
+	 * if _reconnectAsOwner is disabled.
+	 */
+	if (ropt->noOwner && oldUser)
+	{
+		_reconnectAsUser(AH, "-", oldUser);
+		free(oldUser);
+	}
+}
 
 /*
  * This is a routine that is part of the dumper interface, hence the 'Archive*' parameter.
@@ -394,6 +510,8 @@ void PrintTOCSummary(Archive* AHX, RestoreOptions *ropt)
 		default:
 			fmtName = "UNKNOWN";
 	}
+
+	ahprintf(AH, ";     Dump Version: %d.%d-%d\n", AH->vmaj, AH->vmin, AH->vrev);
 	ahprintf(AH, ";     Format: %s\n;\n", fmtName);
 
     ahprintf(AH, ";\n; Selected TOC Entries:\n;\n");
@@ -456,14 +574,14 @@ void StartRestoreBlob(ArchiveHandle* AH, int oid)
 		AH->createdBlobXref = 1;
 	}
 
+	StartTransaction(AH);
+
 	loOid = lo_creat(AH->connection, INV_READ | INV_WRITE);
 	if (loOid == 0)
 		die_horribly(AH, "%s: unable to create BLOB\n", progname);
 
 	ahlog(AH, 1, "Restoring BLOB oid %d as %d\n", oid, loOid);
 
-	StartTransaction(AH);
-
 	InsertBlobXref(AH, oid, loOid);
 
 	AH->loFd = lo_open(AH->connection, loOid, INV_WRITE);
@@ -829,6 +947,8 @@ static void _die_horribly(ArchiveHandle *AH, const char *fmt, va_list ap)
     if (AH)
 	if (AH->connection)
 	    PQfinish(AH->connection);
+	if (AH->blobConnection)
+		PQfinish(AH->blobConnection);
 
     exit(1);
 }
@@ -1113,6 +1233,7 @@ static ArchiveHandle* _allocAH(const char* FileSpec, const ArchiveFormat fmt,
 
     AH->vmaj = K_VERS_MAJOR;
     AH->vmin = K_VERS_MINOR;
+	AH->vrev = K_VERS_REV;
 
 	AH->createDate = time(NULL);
 
@@ -1299,6 +1420,9 @@ static int _tocEntryRequired(TocEntry* te, RestoreOptions *ropt)
     if (ropt->aclsSkip && strcmp(te->desc,"ACL") == 0)
 		return 0;
 
+	if (!ropt->create && strcmp(te->desc,"DATABASE") == 0)
+		return 0;
+
     /* Check if tablename only is wanted */
     if (ropt->selTypes)
     {
@@ -1351,20 +1475,32 @@ static int _tocEntryRequired(TocEntry* te, RestoreOptions *ropt)
     return res;
 }
 
-static void _reconnectAsOwner(ArchiveHandle* AH, TocEntry* te) 
+static void _reconnectAsUser(ArchiveHandle* AH, const char *dbname, char *user)
 {
-    if (te->owner && strlen(te->owner) != 0 && strcmp(AH->currUser, te->owner) != 0) {
+	if (AH->ropt && AH->ropt->noReconnect)
+		return;
+
+	if (user && strlen(user) != 0
+			&& ( (strcmp(AH->currUser, user) != 0) || (strcmp(dbname,"-") != 0)))
+	{
 		if (RestoringToDB(AH))
 		{
-			ReconnectDatabase(AH, te->owner);
-			/* todo pjw - ???? fix for db connection... */
+			ReconnectDatabase(AH, dbname, user);
 		}
 		else
 		{
-			ahprintf(AH, "\\connect - %s\n", te->owner);
+			ahprintf(AH, "\\connect %s %s\n", dbname, user);
 		}
-		AH->currUser = te->owner;
-    }
+		AH->currUser = user;
+    } 
+}
+
+static void _reconnectAsOwner(ArchiveHandle* AH, const char *dbname, TocEntry* te) 
+{
+	if (AH->ropt && AH->ropt->noOwner)
+		return;
+
+	_reconnectAsUser(AH, dbname, te->owner);
 }
 
 static int _printTocEntry(ArchiveHandle* AH, TocEntry* te, RestoreOptions *ropt) 
diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h
index 326cb4df7f10367c0ce4e7295efe92bc436d7221..f2005268798314fd77443afef3a0a3db942dc96b 100644
--- a/src/bin/pg_dump/pg_backup_archiver.h
+++ b/src/bin/pg_dump/pg_backup_archiver.h
@@ -59,7 +59,7 @@ typedef z_stream *z_streamp;
 
 #define K_VERS_MAJOR 1
 #define K_VERS_MINOR 4 
-#define K_VERS_REV 3 
+#define K_VERS_REV 8 
 
 /* Data block types */
 #define BLK_DATA 1
@@ -97,8 +97,7 @@ typedef void	(*SaveArchivePtr)	(struct _archiveHandle* AH);
 typedef void 	(*WriteExtraTocPtr)	(struct _archiveHandle* AH, struct _tocEntry* te);
 typedef void	(*ReadExtraTocPtr)	(struct _archiveHandle* AH, struct _tocEntry* te);
 typedef void	(*PrintExtraTocPtr)	(struct _archiveHandle* AH, struct _tocEntry* te);
-typedef void	(*PrintTocDataPtr)	(struct _archiveHandle* AH, struct _tocEntry* te, 
-						RestoreOptions *ropt);
+typedef void	(*PrintTocDataPtr)	(struct _archiveHandle* AH, struct _tocEntry* te, RestoreOptions *ropt);
 
 typedef int		(*CustomOutPtr)		(struct _archiveHandle* AH, const void* buf, int len);
 
@@ -134,7 +133,7 @@ typedef struct _archiveHandle {
 	char				vrev;
 	int					version;			/* Conveniently formatted version */
 
-	int					debugLevel;			/* Not used. Intended for logging */
+	int					debugLevel;			/* Used for logging (currently only by --verbose) */
 	int					intSize;			/* Size of an integer in the archive */
 	ArchiveFormat		format;				/* Archive format */
 
@@ -158,15 +157,15 @@ typedef struct _archiveHandle {
 	WriteDataPtr		WriteDataPtr; 		/* Called to send some table data to the archive */
 	EndDataPtr			EndDataPtr; 		/* Called when table data dump is finished */
 	WriteBytePtr		WriteBytePtr;		/* Write a byte to output */
-	ReadBytePtr			ReadBytePtr;		/* */
-	WriteBufPtr			WriteBufPtr;	
-	ReadBufPtr			ReadBufPtr;
+	ReadBytePtr			ReadBytePtr;		/* Read a byte from an archive */
+	WriteBufPtr			WriteBufPtr;		/* Write a buffer of output to the archive */
+	ReadBufPtr			ReadBufPtr;			/* Read a buffer of input from the archive */
 	ClosePtr			ClosePtr;			/* Close the archive */
 	WriteExtraTocPtr	WriteExtraTocPtr;	/* Write extra TOC entry data associated with */
 											/* the current archive format */
 	ReadExtraTocPtr		ReadExtraTocPtr;	/* Read extr info associated with archie format */
 	PrintExtraTocPtr	PrintExtraTocPtr;	/* Extra TOC info for format */
-	PrintTocDataPtr		PrintTocDataPtr;
+	PrintTocDataPtr		PrintTocDataPtr;	
 
 	StartBlobsPtr		StartBlobsPtr;
 	EndBlobsPtr			EndBlobsPtr;
@@ -182,6 +181,7 @@ typedef struct _archiveHandle {
 	char				*pghost;
 	char				*pgport;
 	PGconn				*connection;
+	PGconn				*blobConnection;	/* Connection for BLOB xref */
 	int					connectToDB;		/* Flag to indicate if direct DB connection is required */
 	int					pgCopyIn;			/* Currently in libpq 'COPY IN' mode. */
 	PQExpBuffer			pgCopyBuf;			/* Left-over data from incomplete lines in COPY IN */
@@ -265,7 +265,10 @@ 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, char *newUser);
+extern int				ReconnectDatabase(ArchiveHandle *AH, const char* dbname, char *newUser);
+extern int				UserIsSuperuser(ArchiveHandle *AH, char* user);
+extern char*			ConnectedUser(ArchiveHandle *AH);
+extern int				ConnectedUserIsSuperuser(ArchiveHandle *AH);
 
 int ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle* AH);
 int ahprintf(ArchiveHandle* AH, const char *fmt, ...);
diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c
index 17f025ab9fba23a98a878cb4064aa9258c7f480a..adf692797c2ad8b8dbf5242866980ca521cbdb9a 100644
--- a/src/bin/pg_dump/pg_backup_db.c
+++ b/src/bin/pg_dump/pg_backup_db.c
@@ -33,8 +33,10 @@
 
 static const char	*progname = "Archiver(db)";
 
-static void _prompt_for_password(char *username, char *password);
-static void _check_database_version(ArchiveHandle *AH, bool ignoreVersion);
+static void 	_prompt_for_password(char *username, char *password);
+static void 	_check_database_version(ArchiveHandle *AH, bool ignoreVersion);
+static PGconn*	_connectDB(ArchiveHandle *AH, const char* newdbname, char *newUser);
+static int		_executeSqlCommand(ArchiveHandle* AH, PGconn *conn, PQExpBuffer qry, char *desc);
 
 
 static void
@@ -131,7 +133,83 @@ _check_database_version(ArchiveHandle *AH, bool ignoreVersion)
 	PQclear(res);
 }
 
-int ReconnectDatabase(ArchiveHandle *AH, char *newUser)
+/* 
+ * Check if a given user is a superuser.
+ */
+int UserIsSuperuser(ArchiveHandle *AH, char* user)
+{
+	PQExpBuffer			qry = createPQExpBuffer();
+	PGresult			*res;
+	int					i_usesuper;
+	int					ntups;
+	int					isSuper;
+
+	/* Get the superuser setting */
+	appendPQExpBuffer(qry, "select usesuper from pg_user where usename = '%s'", user);
+	res = PQexec(AH->connection, qry->data);
+
+	if (!res)
+		die_horribly(AH, "%s: null result checking superuser status of %s.\n",
+					progname, user);
+
+	if (PQresultStatus(res) != PGRES_TUPLES_OK)
+		die_horribly(AH, "%s: Could not check superuser status of %s. Explanation from backend: %s\n",
+					progname, user, PQerrorMessage(AH->connection));
+
+	ntups = PQntuples(res);
+
+	if (ntups == 0)
+		isSuper = 0;
+	else
+	{
+		i_usesuper = PQfnumber(res, "usesuper");
+		isSuper = (strcmp(PQgetvalue(res, 0, i_usesuper), "t") == 0);
+	}
+	PQclear(res);
+
+	return isSuper;
+}
+
+int ConnectedUserIsSuperuser(ArchiveHandle *AH)
+{
+	return UserIsSuperuser(AH, PQuser(AH->connection));
+}
+
+char* ConnectedUser(ArchiveHandle *AH)
+{
+	return PQuser(AH->connection);
+}
+
+/*
+ * Reconnect the DB associated with the archive handle 
+ */
+int ReconnectDatabase(ArchiveHandle *AH, const char* newdbname, char *newUser)
+{
+	PGconn		*newConn;
+	char		*dbname;
+
+	if (!newdbname || (strcmp(newdbname, "-") == 0) )
+		dbname = PQdb(AH->connection);
+	else
+		dbname = (char*)newdbname;
+
+	/* Let's see if the request is already satisfied */
+	if (strcmp(PQuser(AH->connection), newUser) == 0 && strcmp(newdbname, PQdb(AH->connection)) == 0)
+		return 1;
+
+	newConn = _connectDB(AH, dbname, newUser);
+
+	PQfinish(AH->connection);
+	AH->connection = newConn;
+	strcpy(AH->username, newUser);
+
+	return 1;
+}
+
+/*
+ * Connect to the db again.
+ */
+static PGconn* _connectDB(ArchiveHandle *AH, const char* reqdb, char *requser)
 {
 	int			need_pass;
 	PGconn		*newConn;
@@ -139,47 +217,55 @@ int ReconnectDatabase(ArchiveHandle *AH, char *newUser)
 	char		*pwparam = NULL;
 	int			badPwd = 0;
 	int			noPwd = 0;
+	char		*newdb;
+	char		*newuser;
 
-	ahlog(AH, 1, "Connecting as %s\n", newUser);
+	if (!reqdb || (strcmp(reqdb, "-") == 0) )
+		newdb = PQdb(AH->connection);
+	else
+		newdb = (char*)reqdb;
+
+	if (!requser || (strlen(requser) == 0))
+		newuser = PQuser(AH->connection);
+	else
+		newuser = (char*)requser;
+
+	ahlog(AH, 1, "Connecting to %s as %s\n", newdb, newuser);
 
 	do
 	{
-			need_pass = false;
-			newConn = PQsetdbLogin(PQhost(AH->connection), PQport(AH->connection),
-									NULL, NULL, PQdb(AH->connection), 
-									newUser, pwparam);
-			if (!newConn)
-				die_horribly(AH, "%s: Failed to reconnect (PQsetdbLogin failed).\n", progname);
-
-			if (PQstatus(newConn) == CONNECTION_BAD)
-		    {
-				noPwd = (strcmp(PQerrorMessage(newConn), "fe_sendauth: no password supplied\n") == 0);
-				badPwd = (strncmp(PQerrorMessage(newConn), "Password authentication failed for user", 39)
-							== 0);
-
-				if (noPwd || badPwd) 
-				{
+		need_pass = false;
+		newConn = PQsetdbLogin(PQhost(AH->connection), PQport(AH->connection),
+								NULL, NULL, newdb, 
+								newuser, pwparam);
+		if (!newConn)
+			die_horribly(AH, "%s: Failed to reconnect (PQsetdbLogin failed).\n", progname);
+
+		if (PQstatus(newConn) == CONNECTION_BAD)
+		{
+			noPwd = (strcmp(PQerrorMessage(newConn), "fe_sendauth: no password supplied\n") == 0);
+			badPwd = (strncmp(PQerrorMessage(newConn), "Password authentication failed for user", 39)
+						== 0);
+
+			if (noPwd || badPwd) 
+			{
 
-					if (badPwd)
-						fprintf(stderr, "Password incorrect\n");
+				if (badPwd)
+					fprintf(stderr, "Password incorrect\n");
 
-					fprintf(stderr, "Connecting to %s as %s\n", PQdb(AH->connection), newUser);
+				fprintf(stderr, "Connecting to %s as %s\n", PQdb(AH->connection), newuser);
 
-					need_pass = true;
-					_prompt_for_password(newUser, password);
-					pwparam = password; 
-				}
-				else
-					die_horribly(AH, "%s: Could not reconnect. %s\n", progname, PQerrorMessage(newConn));
+				need_pass = true;
+				_prompt_for_password(newuser, password);
+				pwparam = password; 
 			}
+			else
+				die_horribly(AH, "%s: Could not reconnect. %s\n", progname, PQerrorMessage(newConn));
+		}
 
 	} while (need_pass);
 
-	PQfinish(AH->connection);
-	AH->connection = newConn;
-	strcpy(AH->username, newUser);
-
-	return 1;
+	return newConn;
 }
 
 
@@ -247,25 +333,46 @@ PGconn* ConnectDatabase(Archive *AHX,
 	/* check for version mismatch */
 	_check_database_version(AH, ignoreVersion);
 
-	AH->currUser = PQuser(AH->connection);
+	/*
+     * AH->currUser = PQuser(AH->connection);
+	 *	
+	 * Removed because it prevented an initial \connect
+	 * when dumping to SQL in pg_dump.
+	 */
 
 	return AH->connection;
 }
 
+/* Public interface */
 /* Convenience function to send a query. Monitors result to handle COPY statements */
 int ExecuteSqlCommand(ArchiveHandle* AH, PQExpBuffer qry, char *desc)
+{
+	return _executeSqlCommand(AH, AH->connection, qry, desc);
+}
+
+/* 
+ * Handle command execution. This is used to execute a command on more than one connection,
+ * but the 'pgCopyIn' setting assumes the COPY commands are ONLY executed on the primary
+ * setting...an error will be raised otherwise.
+ */
+static int _executeSqlCommand(ArchiveHandle* AH, PGconn *conn, PQExpBuffer qry, char *desc)
 {
 	PGresult		*res;
 
 	/* fprintf(stderr, "Executing: '%s'\n\n", qry->data); */
-	res = PQexec(AH->connection, qry->data);
+	res = PQexec(conn, qry->data);
 	if (!res)
 		die_horribly(AH, "%s: %s. No result from backend.\n", progname, desc);
 
     if (PQresultStatus(res) != PGRES_COMMAND_OK && PQresultStatus(res) != PGRES_TUPLES_OK)
 	{
 		if (PQresultStatus(res) == PGRES_COPY_IN)
+		{
+			if (conn != AH->connection)
+				die_horribly(AH, "%s: COPY command execute in non-primary connection.\n", progname);
+
 			AH->pgCopyIn = 1;
+		}
 		else 
 			die_horribly(AH, "%s: %s. Code = %d. Explanation from backend: '%s'.\n",
 						progname, desc, PQresultStatus(res), PQerrorMessage(AH->connection));
@@ -467,7 +574,7 @@ void FixupBlobRefs(ArchiveHandle *AH, char *tablename)
 								" WHERE a.attnum > 0 AND a.attrelid = c.oid AND a.atttypid = t.oid "
 								" AND t.typname = 'oid' AND c.relname = '%s';", tablename);
 
-	res = PQexec(AH->connection, tblQry->data);
+	res = PQexec(AH->blobConnection, tblQry->data);
 	if (!res)
 		die_horribly(AH, "%s: could not find OID attrs of %s. Explanation from backend '%s'\n",
 						progname, tablename, PQerrorMessage(AH->connection));
@@ -493,7 +600,7 @@ void FixupBlobRefs(ArchiveHandle *AH, char *tablename)
 
 		ahlog(AH, 10, " - sql = %s\n", tblQry->data);
 
-		uRes = PQexec(AH->connection, tblQry->data);
+		uRes = PQexec(AH->blobConnection, tblQry->data);
 		if (!uRes)
 			die_horribly(AH, "%s: could not update attr %s of table %s. Explanation from backend '%s'\n",
 								progname, attr, tablename, PQerrorMessage(AH->connection));
@@ -516,16 +623,22 @@ void CreateBlobXrefTable(ArchiveHandle* AH)
 {
 	PQExpBuffer		qry = createPQExpBuffer();
 
+	/* IF we don't have a BLOB connection, then create one */
+	if (!AH->blobConnection)
+	{
+		AH->blobConnection = _connectDB(AH, NULL, NULL);
+	}
+
 	ahlog(AH, 1, "Creating table for BLOBS xrefs\n");
 
 	appendPQExpBuffer(qry, "Create Temporary Table %s(oldOid oid, newOid oid);", BLOB_XREF_TABLE);
 
-	ExecuteSqlCommand(AH, qry, "can not create BLOB xref table '" BLOB_XREF_TABLE "'");
+	_executeSqlCommand(AH, AH->blobConnection, qry, "can not create BLOB xref table '" BLOB_XREF_TABLE "'");
 
 	resetPQExpBuffer(qry);
 
 	appendPQExpBuffer(qry, "Create Unique Index %s_ix on %s(oldOid)", BLOB_XREF_TABLE, BLOB_XREF_TABLE);
-	ExecuteSqlCommand(AH, qry, "can not create index on BLOB xref table '" BLOB_XREF_TABLE "'");
+	_executeSqlCommand(AH, AH->blobConnection, qry, "can not create index on BLOB xref table '" BLOB_XREF_TABLE "'");
 }
 
 void InsertBlobXref(ArchiveHandle* AH, int old, int new)
@@ -534,7 +647,7 @@ void InsertBlobXref(ArchiveHandle* AH, int old, int new)
 
 	appendPQExpBuffer(qry, "Insert Into %s(oldOid, newOid) Values (%d, %d);", BLOB_XREF_TABLE, old, new);
 
-	ExecuteSqlCommand(AH, qry, "can not create BLOB xref entry");
+	_executeSqlCommand(AH, AH->blobConnection, qry, "can not create BLOB xref entry");
 }
 
 void StartTransaction(ArchiveHandle* AH)
diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c
index ca1bdf7a61f499b3434ed27590f0ad004eca49e4..6a3b2122064593f937bb93c93e3fe7dbb0481833 100644
--- a/src/bin/pg_dump/pg_backup_tar.c
+++ b/src/bin/pg_dump/pg_backup_tar.c
@@ -55,7 +55,7 @@ static void		_EndBlobs(ArchiveHandle* AH, TocEntry* te);
 
 
 #ifdef HAVE_LIBZ
-	//typedef gzFile	ThingFile;
+	/* typedef gzFile	ThingFile; */
 	typedef FILE    ThingFile;
 #else
 	typedef	FILE	ThingFile;
@@ -159,7 +159,7 @@ void InitArchiveFmt_Tar(ArchiveHandle* AH)
 		ctx->tarFHpos = 0;
 
 		/* Make unbuffered since we will dup() it, and the buffers screw each other */
-		//setvbuf(ctx->tarFH, NULL, _IONBF, 0);
+		/* setvbuf(ctx->tarFH, NULL, _IONBF, 0); */
 
 		ctx->hasSeek = (fseek(ctx->tarFH, 0, SEEK_CUR) == 0);
 
@@ -186,7 +186,7 @@ void InitArchiveFmt_Tar(ArchiveHandle* AH)
 		}
 
 		/* Make unbuffered since we will dup() it, and the buffers screw each other */
-		//setvbuf(ctx->tarFH, NULL, _IONBF, 0);
+		/* setvbuf(ctx->tarFH, NULL, _IONBF, 0); */
 
 		ctx->tarFHpos = 0;
 
@@ -487,7 +487,7 @@ static int	_WriteData(ArchiveHandle* AH, const void* data, int dLen)
 
 	tarWrite((void*)data, dLen, tctx->TH);
 
-    //GZWRITE((void*)data, 1, dLen, tctx->TH->FH);
+    /* GZWRITE((void*)data, 1, dLen, tctx->TH->FH); */
 
     return dLen;
 }
@@ -764,6 +764,7 @@ static void	_CloseArchive(ArchiveHandle* AH)
 		ropt = NewRestoreOptions();
 		ropt->dropSchema = 1;
 		ropt->compression = 0;
+		ropt->superuser = PQuser(AH->connection);
 
 		savVerbose = AH->public.verbose;
 		AH->public.verbose = 0;
@@ -1116,10 +1117,10 @@ static void _tarWriteHeader(TAR_MEMBER* th)
 	sprintf(&h[297], "%.31s", ""); /* How do I get group reliably? Do I need to? */
 
 	/* Maj Dev 8 */
-	// sprintf(&h[329], "%8o", 0);
+	/* sprintf(&h[329], "%8o", 0); */
 
 	/* Min Dev */
-	// sprintf(&h[337], "%8o", 0);
+	/* sprintf(&h[337], "%8o", 0); */
 
 
 	while ( (sum = _tarChecksum(h)) != lastSum)
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 7c89573e2910ec9dbb17896e695630d2a55dd38d..105376c4f310452a8c69c27a99f9fa7faa1d14d2 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -22,7 +22,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.161 2000/07/24 06:24:26 pjw Exp $
+ *	  $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.162 2000/08/01 15:51:44 pjw Exp $
  *
  * Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
  *
@@ -66,6 +66,19 @@
  *		 - Support for BLOB output.
  *		 - Sort archive by OID, put some items at end (out of OID order)
  *
+ * Modifications - 28-Jul-2000 - pjw@rhyme.com.au (1.45)
+ *
+ * 		Added --create, --no-owner, --superuser, --no-reconnect (pg_dump & pg_restore)
+ *		Added code to dump 'Create Schema' statement (pg_dump)
+ *		Don't bother to disable/enable triggers if we don't have a superuser (pg_restore)
+ *		Cleaned up code for reconnecting to database.
+ *		Force a reconnect as superuser before enabling/disabling triggers.
+ *
+ * Modifications - 31-Jul-2000 - pjw@rhyme.com.au (1.46, 1.47)
+ *		Added & Removed --throttle (pg_dump)
+ *		Fixed minor bug in language dumping code: expbuffres were not being reset.
+ *		Fixed version number initialization in _allocAH (pg_backup_archiver.c)
+ *
  *-------------------------------------------------------------------------
  */
 
@@ -118,7 +131,7 @@ static void AddAcl(char *aclbuf, const char *keyword);
 static char *GetPrivileges(const char *s);
 
 static int dumpBlobs(Archive *AH, char*, void*);
-
+static int dumpDatabase(Archive *AH);
 
 extern char *optarg;
 extern int	optind,
@@ -163,6 +176,7 @@ help(const char *progname)
 	puts(
 		"  -a, --data-only          dump out only the data, not the schema\n"
 	   	"  -c, --clean              clean (drop) schema prior to create\n"
+		"  -C, --create             output commands to create database\n"
 		"  -d, --inserts            dump data as INSERT, rather than COPY, commands\n"
 		"  -D, --attribute-inserts  dump data as INSERT commands with attribute names\n"
 		"  -f, --file               specify output file name\n"
@@ -172,8 +186,11 @@ help(const char *progname)
 		"  -n, --no-quotes          suppress most quotes around identifiers\n"
 		"  -N, --quotes             enable most quotes around identifiers\n"
 		"  -o, --oids               dump object ids (oids)\n"
+		"  -O, --no-owner           don't output \\connect commands in plain text format\n"
 		"  -p, --port <port>        server port number\n"
+		"  -R, --no-reconnect       disable ALL reconnections to the database in plain text format\n"
 		"  -s, --schema-only        dump out only the schema, no data\n"
+		"  -S, --superuser <name>   specify the superuser username to use in plain text format\n"
 		"  -t, --table <table>      dump for this table only\n"
 		"  -u, --password           use password authentication\n"
 		"  -v, --verbose            verbose\n"
@@ -184,6 +201,7 @@ help(const char *progname)
 	puts(
 		"  -a                       dump out only the data, no schema\n"
 		"  -c                       clean (drop) schema prior to create\n"
+		"  -C                       output commands to create database\n"
 		"  -d                       dump data as INSERT, rather than COPY, commands\n"
 		"  -D                       dump data as INSERT commands with attribute names\n"
 		"  -f                       specify output file name\n"
@@ -193,8 +211,11 @@ help(const char *progname)
 		"  -n                       suppress most quotes around identifiers\n"
 		"  -N                       enable most quotes around identifiers\n"
 		"  -o                       dump object ids (oids)\n"
+		"  -O                       don't output \\connect commands in plain text format\n"
 		"  -p <port>                server port number\n"
+		"  -R                       disable ALL reconnections to the database in plain text format\n"
 		"  -s                       dump out only the schema, no data\n"
+		"  -S <name>                specify the superuser username to use in plain text format\n"
 		"  -t <table>               dump for this table only\n"
 		"  -u                       use password authentication\n"
 		"  -v                       verbose\n"
@@ -264,6 +285,7 @@ isViewRule(char *relname)
  *	- this routine is called by the Archiver when it wants the table
  *	  to be dumped.
  */
+
 static int 
 dumpClasses_nodumpData(Archive *fout, char* oid, void *dctxv)
 {
@@ -277,6 +299,9 @@ dumpClasses_nodumpData(Archive *fout, char* oid, void *dctxv)
 	bool		copydone;
 	char		copybuf[COPYBUFSIZ];
 
+    if (g_verbose)
+        fprintf(stderr, "%s dumping out the contents of table %s\n", g_comment_start, classname);
+
 	if (oids == true)
 	{
 		/* 
@@ -325,6 +350,7 @@ dumpClasses_nodumpData(Archive *fout, char* oid, void *dctxv)
 		else
 		{
 			copydone = false;
+
 			while (!copydone)
 			{
 				ret = PQgetline(g_conn, copybuf, COPYBUFSIZ);
@@ -350,6 +376,46 @@ dumpClasses_nodumpData(Archive *fout, char* oid, void *dctxv)
 							break;
 					}
 				}
+
+				/* 
+				 * THROTTLE:
+				 *
+				 * There was considerable discussion in late July, 2000 regarding slowing down
+				 * pg_dump when backing up large tables. Users with both slow & fast (muti-processor)
+				 * machines experienced performance degradation when doing a backup.
+				 *
+				 * Initial attempts based on sleeping for a number of ms for each ms of work were deemed
+				 * too complex, then a simple 'sleep in each loop' implementation was suggested. The latter
+				 * failed because the loop was too tight. Finally, the following was implemented:
+				 *
+				 * If throttle is non-zero, then
+				 * 		See how long since the last sleep.
+				 *		Work out how long to sleep (based on ratio).
+				 * 		If sleep is more than 100ms, then 
+			     *			sleep 
+				 *			reset timer
+				 *		EndIf
+				 * EndIf
+				 *
+				 * where the throttle value was the number of ms to sleep per ms of work. The calculation was 
+				 * done in each loop.
+				 *
+				 * Most of the hard work is done in the backend, and this solution still did not work 
+				 * particularly well: on slow machines, the ratio was 50:1, and on medium paced machines, 1:1,
+				 * and on fast multi-processor machines, it had little or no effect, for reasons that were unclear.
+				 *
+				 * Further discussion ensued, and the proposal was dropped.
+				 *
+				 * For those people who want this feature, it can be implemented using gettimeofday in each
+				 * loop, calculating the time since last sleep, multiplying that by the sleep ratio, then
+				 * if the result is more than a preset 'minimum sleep time' (say 100ms), call the 'select'
+				 * function to sleep for a subsecond period ie.
+				 *
+				 *        select(0, NULL, NULL, NULL, &tvi);
+				 *
+				 * This will return after the interval specified in the structure tvi. Fianally, call
+				 * gettimeofday again to save the 'last sleep time'.
+				 */	
 			}
 			archprintf(fout, "\\.\n");
 		}
@@ -366,11 +432,10 @@ dumpClasses_nodumpData(Archive *fout, char* oid, void *dctxv)
 			exit_nicely(g_conn);
 		}
 	}
+
 	return 1;
 }
 
-
-
 static int
 dumpClasses_dumpData(Archive *fout, char* oid, void *dctxv)
 {
@@ -498,7 +563,7 @@ dumpClasses(const TableInfo *tblinfo, const int numTables, Archive *fout,
 
 
 	if (g_verbose)
-		fprintf(stderr, "%s dumping out the contents of %s %d table%s/sequence%s %s\n",
+		fprintf(stderr, "%s preparing to dump out the contents of %s %d table%s/sequence%s %s\n",
 				g_comment_start, all_only,
 				(onlytable == NULL) ? numTables : 1,
 		  (onlytable == NULL) ? "s" : "", (onlytable == NULL) ? "s" : "",
@@ -536,7 +601,7 @@ dumpClasses(const TableInfo *tblinfo, const int numTables, Archive *fout,
 		if (!onlytable || (!strcmp(classname, onlytable)))
 		{
 			if (g_verbose)
-				fprintf(stderr, "%s dumping out the contents of Table '%s' %s\n",
+				fprintf(stderr, "%s preparing to dump out the contents of Table '%s' %s\n",
 						g_comment_start, classname, g_comment_end);
 
 			/* becomeUser(fout, tblinfo[i].usename); */
@@ -587,7 +652,11 @@ main(int argc, char **argv)
 	bool		ignore_version = false;
 	int			plainText = 0;
 	int			outputClean = 0;
+	int			outputCreate = 0;
 	int			outputBlobs = 0;
+	int			outputNoOwner = 0;
+	int			outputNoReconnect = 0;
+	char		*outputSuperuser = NULL;
 
 	RestoreOptions	*ropt;
 
@@ -596,17 +665,21 @@ main(int argc, char **argv)
 		{"data-only", no_argument, NULL, 'a'},
 		{"blobs", no_argument, NULL, 'b' },
 		{"clean", no_argument, NULL, 'c'},
+		{"create", no_argument, NULL, 'C'},
 		{"file", required_argument, NULL, 'f'},
 		{"format", required_argument, NULL, 'F'},
 		{"inserts", no_argument, NULL, 'd'},
 		{"attribute-inserts", no_argument, NULL, 'D'},
 		{"host", required_argument, NULL, 'h'},
 		{"ignore-version", no_argument, NULL, 'i'},
+		{"no-reconnect", no_argument, NULL, 'R'},
 		{"no-quotes", no_argument, NULL, 'n'},
 		{"quotes", no_argument, NULL, 'N'},
 		{"oids", no_argument, NULL, 'o'},
+		{"no-owner", no_argument, NULL, 'O'},
 		{"port", required_argument, NULL, 'p'},
 		{"schema-only", no_argument, NULL, 's'},
+		{"superuser", required_argument, NULL, 'S'},
 		{"table", required_argument, NULL, 't'},
 		{"password", no_argument, NULL, 'u'},
 		{"verbose", no_argument, NULL, 'v'},
@@ -641,10 +714,11 @@ main(int argc, char **argv)
 	}
 
 #ifdef HAVE_GETOPT_LONG
-	while ((c = getopt_long(argc, argv, "acdDf:F:h:inNop:st:uvxzZ:V?", long_options, &optindex)) != -1)
+	while ((c = getopt_long(argc, argv, "acCdDf:F:h:inNoOp:sS:t:uvxzZ:V?", long_options, &optindex)) != -1)
 #else
-	while ((c = getopt(argc, argv, "acdDf:F:h:inNop:st:uvxzZ:V?-")) != -1)
+	while ((c = getopt(argc, argv, "acCdDf:F:h:inNoOp:sS:t:uvxzZ:V?-")) != -1)
 #endif
+
 	{
 		switch (c)
 		{
@@ -660,6 +734,11 @@ main(int argc, char **argv)
 				outputClean = 1;
  				break;
  
+			case 'C':			/* Create DB */
+
+				outputCreate = 1;
+				break;
+
 			case 'd':			/* dump data as proper insert strings */
 				dumpData = true;
 				break;
@@ -690,12 +769,21 @@ main(int argc, char **argv)
 			case 'o':			/* Dump oids */
 				oids = true;
 				break;
+			case 'O':			/* Don't reconnect to match owner */
+				outputNoOwner = 1;
+				break;
 			case 'p':			/* server port */
 				pgport = optarg;
 				break;
+			case 'R':			/* No reconnect */
+				outputNoReconnect = 1;
+				break;
 			case 's':			/* dump schema only */
 				schemaOnly = true;
 				break;
+			case 'S':			/* Username for superuser in plain text output */
+				outputSuperuser = strdup(optarg);
+				break;
 			case 't':			/* Dump data for this table only */
 				{
 					int			i;
@@ -852,6 +940,10 @@ main(int argc, char **argv)
 
 	g_last_builtin_oid = findLastBuiltinOid();
 
+	/* Dump the database definition */
+	if (!dataOnly)
+		dumpDatabase(g_fout);
+
 	if (oids == true)
 		setMaxOid(g_fout);
 
@@ -878,6 +970,7 @@ main(int argc, char **argv)
 
 	/* Now sort the output nicely */
 	SortTocByOID(g_fout);
+	MoveToStart(g_fout, "DATABASE");
 	MoveToEnd(g_fout, "TABLE DATA");
 	MoveToEnd(g_fout, "BLOBS");
 	MoveToEnd(g_fout, "INDEX");
@@ -890,6 +983,15 @@ main(int argc, char **argv)
 		ropt->filename = (char*)filename;
 		ropt->dropSchema = outputClean;
 		ropt->aclsSkip = aclsSkip;
+		ropt->superuser = outputSuperuser;
+		ropt->create = outputCreate;
+		ropt->noOwner = outputNoOwner;
+		ropt->noReconnect = outputNoReconnect;
+
+		if (outputSuperuser)
+			ropt->superuser = outputSuperuser;
+		else
+			ropt->superuser = PQuser(g_conn);
 
 		if (compressLevel == -1)
 		    ropt->compression = 0;
@@ -906,6 +1008,60 @@ main(int argc, char **argv)
 	exit(0);
 }
 
+/*
+ * dumpDatabase:
+ *	dump the database definition
+ *
+ */
+static int 
+dumpDatabase(Archive *AH)
+{
+	PQExpBuffer		dbQry = createPQExpBuffer();
+	PQExpBuffer		delQry = createPQExpBuffer();
+	PQExpBuffer		creaQry = createPQExpBuffer();
+	PGresult		*res;
+	int				ntups;
+	int				i_dba;
+
+	if (g_verbose)
+		fprintf(stderr, "%s saving database definition\n", g_comment_start);
+
+	/* Get the dba */
+	appendPQExpBuffer(dbQry, "select pg_get_userbyid(datdba) as dba from pg_database"
+							" where datname = '%s'", PQdb(g_conn));
+
+	res = PQexec(g_conn, dbQry->data);
+	if (!res ||
+		PQresultStatus(res) != PGRES_TUPLES_OK)
+	{
+		fprintf(stderr, "getDatabase(): SELECT failed.  Explanation from backend: '%s'.\n", 
+						PQerrorMessage(g_conn));
+		exit_nicely(g_conn);
+	}
+
+	ntups = PQntuples(res);
+
+	if (ntups != 1)
+	{
+		fprintf(stderr, "getDatabase(): SELECT returned %d databases.\n", ntups);
+		exit_nicely(g_conn);
+	}
+
+	appendPQExpBuffer(creaQry, "Create Database \"%s\";\n", PQdb(g_conn));
+	appendPQExpBuffer(delQry, "Drop Database \"%s\";\n", PQdb(g_conn));
+	i_dba = PQfnumber(res, "dba");
+
+	ArchiveEntry(AH, "0" /* OID */, PQdb(g_conn) /* Name */, "DATABASE", NULL, 
+						creaQry->data /* Create */, delQry->data /*Del*/,
+						"" /* Copy */, PQgetvalue(res, 0, i_dba) /*Owner*/, 
+						NULL /* Dumper */, NULL /* Dumper Arg */);	
+
+	PQclear(res);
+
+	return 1;
+}
+
+
 /*
  * dumpBlobs:
  *	dump all blobs
@@ -2652,6 +2808,9 @@ dumpProcLangs(Archive *fout, FuncInfo *finfo, int numFuncs,
 
 		free(lanname);
 		free(lancompiler);
+
+		resetPQExpBuffer(defqry);
+		resetPQExpBuffer(delqry);
 	}
 
 	PQclear(res);
diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c
index b39d8f7802bee007b4800fa235606360b273f5fe..e85a42a2317271225fe7bb94ee371fe28f077ed1 100644
--- a/src/bin/pg_dump/pg_restore.c
+++ b/src/bin/pg_dump/pg_restore.c
@@ -37,7 +37,15 @@
  *
  * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
  *
- *	Initial version. Command processing taken from original pg_dump.
+ *		Initial version. Command processing taken from original pg_dump.
+ *
+ * Modifications - 28-Jul-2000 - pjw@rhyme.com.au (1.45)
+ *
+ * 		Added --create, --no-owner, --superuser, --no-reconnect (pg_dump & pg_restore)
+ *		Added code to dump 'Create Schema' statement (pg_dump)
+ *		Don't bother to disable/enable triggers if we don't have a superuser (pg_restore)
+ *		Cleaned up code for reconnecting to database.
+ *		Force a reconnect as superuser before enabling/disabling triggers.
  *
  *-------------------------------------------------------------------------
  */
@@ -83,6 +91,7 @@ typedef struct option optType;
 #ifdef HAVE_GETOPT_H
 struct option cmdopts[] = {	
 				{ "clean", 0, NULL, 'c' },
+				{ "create", 0, NULL, 'C' },
 				{ "data-only", 0, NULL, 'a' },
 				{ "dbname", 1, NULL, 'd' },
 				{ "file", 1, NULL, 'f' },
@@ -93,12 +102,15 @@ struct option cmdopts[] = {
 				{ "index", 2, NULL, 'I'},
 				{ "list", 0, NULL, 'l'},
 				{ "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, 'O' },
+				{ "orig-order", 0, NULL, 'N'},
 				{ "password", 0, NULL, 'u' },
 				{ "rearrange", 0, NULL, 'r'},
 				{ "schema-only", 0, NULL, 's' },
+				{ "superuser", 1, NULL, 'S' },
 				{ "table", 2, NULL, 't'},
 				{ "trigger", 2, NULL, 'T' },
 				{ "use-list", 1, NULL, 'U'},
@@ -120,9 +132,9 @@ int main(int argc, char **argv)
 	progname = *argv;
 
 #ifdef HAVE_GETOPT_LONG
-	while ((c = getopt_long(argc, argv, "acd:f:F:h:i:loOp:st:T:u:U:vx", cmdopts, NULL)) != EOF)
+	while ((c = getopt_long(argc, argv, "acCd:f:F:h:i:lNoOp:rRsSt:T:uU:vx", cmdopts, NULL)) != EOF)
 #else
-	while ((c = getopt(argc, argv, "acd:f:F:h:i:loOp:st:T:u:U:vx")) != -1)
+	while ((c = getopt(argc, argv, "acCd:f:F:h:i:lNoOp:rRsSt:T:uU:vx")) != -1)
 #endif
 	{
 		switch (c)
@@ -134,6 +146,9 @@ int main(int argc, char **argv)
 								 * create */
 				opts->dropSchema = 1;
 				break;
+			case 'C':
+				opts->create = 1;
+				break;
 			case 'd':
 				if (strlen(optarg) != 0)
 				{
@@ -155,11 +170,14 @@ int main(int argc, char **argv)
 			case 'i':
 				opts->ignoreVersion = 1;
 				break;
+			case 'N':
+				opts->origOrder = 1;
+				break;
 			case 'o':
 				opts->oidOrder = 1;
 				break;
 			case 'O':
-				opts->origOrder = 1;
+				opts->noOwner = 1;
 				break;
 			case 'p':
 				if (strlen(optarg) != 0)
@@ -168,6 +186,9 @@ int main(int argc, char **argv)
 			case 'r':
 				opts->rearrange = 1;
 				break;
+			case 'R':
+				opts->noReconnect = 1;
+				break;
 			case 'P': /* Function */
 				opts->selTypes = 1;
 				opts->selFunction = 1;
@@ -186,6 +207,10 @@ int main(int argc, char **argv)
 			case 's':			/* dump schema only */
 				opts->schemaOnly = 1;
 				break;
+			case 'S':			/* Superuser username */
+				if (strlen(optarg) != 0)
+					opts->superuser = strdup(optarg);
+				break;
 			case 't':			/* Dump data for this table only */
 				opts->selTypes = 1;
 				opts->selTable = 1;
@@ -270,6 +295,9 @@ int main(int argc, char **argv)
 		MoveToEnd(AH, "ACL");
     }
 
+	/* Database MUST be at start */
+	MoveToStart(AH, "DATABASE");
+
     if (opts->tocSummary) {
 		PrintTOCSummary(AH, opts);
     } else {
@@ -289,17 +317,21 @@ static void usage(const char *progname)
 	    "  -a, --data-only             \t dump out only the data, no schema\n"
 		"  -d, --dbname <name>         \t specify database name\n"
 	    "  -c, --clean                 \t clean(drop) schema prior to create\n"
+		"  -C, --create                \t output commands to create the database\n"
 	    "  -f filename                 \t script output filename\n"
 	    "  -F, --format {c|f}          \t specify backup file format\n"
 		"  -h, --host <hostname>       \t server host name\n"
 	    "  -i, --index[=name]          \t dump indexes or named index\n"
 	    "  -l, --list                  \t dump summarized TOC for this file\n"
+		"  -N, --orig-order            \t dump in original dump order\n"
 	    "  -o, --oid-order             \t dump in oid order\n"
-	    "  -O, --orig-order            \t dump in original dump order\n"
+		"  -O, --no-owner              \t don't output reconnect to database to match object owner\n"
 		"  -p, --port <port>           \t server port number\n"
 		"  -P, --function[=name]       \t dump functions or named function\n"
 	    "  -r, --rearrange             \t rearrange output to put indexes etc at end\n"
+		"  -R, --no-reconnect          \t disallow ALL reconnections to the database\n"
 	    "  -s, --schema-only           \t dump out only the schema, no data\n"
+		"  -S, --superuser <name>      \t specify the superuser username to use in disabling triggers\n"
 	    "  -t [table], --table[=table] \t dump for this table only\n"
 	    "  -T, --trigger[=name]        \t dump triggers or named trigger\n"
 		"  -u, --password              \t use password authentication\n"
@@ -312,19 +344,23 @@ static void usage(const char *progname)
 	fprintf(stderr,
 	"usage:  %s [options] [backup file]\n"
 	    "  -a                          \t dump out only the data, no schema\n"
-		"  -d,          <name>         \t specify database name\n"
+		"  -d <name>                   \t specify database name\n"
 	    "  -c                          \t clean(drop) schema prior to create\n"
-	    "  -f filename NOT IMPLEMENTED \t script output filename\n"
-	    "  -F           {c|f}          \t specify backup file format\n"
-		"  -h,        <hostname>       \t server host name\n"
+		"  -C                          \t output commands to create the database\n"
+	    "  -f filename                 \t script output filename\n"
+	    "  -F {c|f}                    \t specify backup file format\n"
+		"  -h <hostname>               \t server host name\n"
 	    "  -i name                     \t dump indexes or named index\n"
 	    "  -l                          \t dump summarized TOC for this file\n"
+		"  -N                          \t dump in original dump order\n"
 	    "  -o                          \t dump in oid order\n"
-	    "  -O                          \t dump in original dump order\n"
-		"  -p         <port>           \t server port number\n"
+		"  -O                          \t don't output reconnect to database to match object owner\n"
+		"  -p <port>                   \t server port number\n"
 		"  -P name                     \t dump functions or named function\n"
 	    "  -r                          \t rearrange output to put indexes etc at end\n"
+		"  -R                          \t disallow ALL reconnections to the database\n"
 	    "  -s                          \t dump out only the schema, no data\n"
+		"  -S <name>                   \t specify the superuser username to use in disabling triggers\n"
 	    "  -t name                     \t dump for this table only\n"
 	    "  -T name                     \t dump triggers or named trigger\n"
 		"  -u                          \t use password authentication\n"