diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h
index 0bde27b3e56e6669727582fe0a85f67752180af1..bf453c73ab0fdc01e6403e04ea0a101fe0d792fa 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.10 2001/04/01 05:42:50 pjw Exp $
+ *		$Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup.h,v 1.11 2001/04/25 07:03:19 pjw Exp $
  *
  * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
  *
@@ -50,6 +50,9 @@
 #define atooid(x)  ((Oid) strtoul((x), NULL, 10))
 #define oidcmp(x,y) ( ((x) < (y) ? -1 : ((x) > (y)) ?  1 : 0) )
 #define oideq(x,y) ( (x) == (y) )
+#define oidle(x,y) ( (x) <= (y) )
+#define oidge(x,y) ( (x) >= (y) )
+#define oidzero(x) ( (x) == 0 )
 
 typedef enum _archiveFormat
 {
@@ -66,7 +69,10 @@ typedef enum _archiveFormat
  */
 typedef struct _Archive
 {
-	int			verbose;
+	int				verbose;
+	int				remoteVersion;
+	int				minRemoteVersion;
+	int				maxRemoteVersion;
 	/* The rest is private */
 } Archive;
 
@@ -115,6 +121,7 @@ typedef struct _restoreOptions
 	int			limitToList;
 	int			compression;
 
+	int			suppressDumpWarnings;		/* Suppress output of WARNING entries to stderr */
 } RestoreOptions;
 
 /*
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index af98a05dc3c56076d676dc6826389f5845ed1954..a1faab4b609aa92dfd0d20f9264f7a56de381b24 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.24 2001/04/14 13:11:03 pjw Exp $
+ *		$Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.25 2001/04/25 07:03:19 pjw Exp $
  *
  * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
  *
@@ -169,6 +169,10 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
 		if (AH->version < K_VERS_1_3)
 			die_horribly(AH, "Direct database connections are not supported in pre-1.3 archives");
 
+		/* XXX Should get this from the archive */
+		AHX->minRemoteVersion = 070100;
+		AHX->maxRemoteVersion = 999999;
+
 		ConnectDatabase(AHX, ropt->dbname, ropt->pghost, ropt->pgport,
 						ropt->requirePassword, ropt->ignoreVersion);
 
@@ -260,6 +264,18 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
 		/* Work out what, if anything, we want from this entry */
 		reqs = _tocEntryRequired(te, ropt);
 
+		/* Dump any relevant dump warnings to stderr */
+		if (!ropt->suppressDumpWarnings && strcmp(te->desc, "WARNING") == 0)
+		{
+			if (!ropt->dataOnly && te->defn != NULL && strlen(te->defn) != 0) 
+			{
+				fprintf(stderr, "%s: Warning from original dump file:\n%s\n", progname, te->defn);
+			} else if (te->copyStmt != NULL && strlen(te->copyStmt) != 0)
+			{
+				fprintf(stderr, "%s: Warning from original dump file:\n%s\n", progname, te->copyStmt);
+			}
+	 	}
+
 		if ((reqs & 1) != 0)	/* We want the schema */
 		{
 			/* Reconnect if necessary */
@@ -405,6 +421,7 @@ NewRestoreOptions(void)
 	opts = (RestoreOptions *) calloc(1, sizeof(RestoreOptions));
 
 	opts->format = archUnknown;
+	opts->suppressDumpWarnings = false;
 
 	return opts;
 }
@@ -1419,7 +1436,8 @@ _discoverArchiveFormat(ArchiveHandle *AH)
 	cnt = fread(sig, 1, 5, fh);
 
 	if (cnt != 5)
-		die_horribly(AH, "%s: input file is too short, or is unreadable\n", progname);
+		die_horribly(AH, "%s: input file is too short, or is unreadable (read %d, expected 5)\n", 
+							progname, cnt);
 
 	/* Save it, just in case we need it later */
 	strncpy(&AH->lookahead[0], sig, 5);
diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h
index c9206af3b1087a240a268e18b01df48441b7daa7..bb5b03ae1f711948f128dfacbacce3f05ed0983f 100644
--- a/src/bin/pg_dump/pg_backup_archiver.h
+++ b/src/bin/pg_dump/pg_backup_archiver.h
@@ -17,7 +17,7 @@
  *
  *
  * IDENTIFICATION
- *		$Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.31 2001/04/14 13:11:03 pjw Exp $
+ *		$Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.32 2001/04/25 07:03:19 pjw Exp $
  *
  * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
  *	-	Initial version.
@@ -68,7 +68,7 @@ typedef z_stream *z_streamp;
 
 #define K_VERS_MAJOR 1
 #define K_VERS_MINOR 5
-#define K_VERS_REV 3 
+#define K_VERS_REV 5 
 
 /* Data block types */
 #define BLK_DATA 1
diff --git a/src/bin/pg_dump/pg_backup_custom.c b/src/bin/pg_dump/pg_backup_custom.c
index b4311e8f87b8c830ce8eb6109d34c32104b00eb1..3e839ca38bf4073d16493540b6b2655b5ca6ba2f 100644
--- a/src/bin/pg_dump/pg_backup_custom.c
+++ b/src/bin/pg_dump/pg_backup_custom.c
@@ -19,7 +19,7 @@
  *
  *
  * IDENTIFICATION
- *		$Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_custom.c,v 1.10 2001/04/01 05:42:51 pjw Exp $
+ *		$Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_custom.c,v 1.11 2001/04/25 07:03:19 pjw Exp $
  *
  * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
  *
@@ -786,6 +786,7 @@ _ReadBuf(ArchiveHandle *AH, void *buf, int len)
 
 	res = fread(buf, 1, len, AH->FH);
 	ctx->filePos += res;
+
 	return res;
 }
 
@@ -854,7 +855,10 @@ _getFilePos(ArchiveHandle *AH, lclContext *ctx)
 	{
 		pos = ftell(AH->FH);
 		if (pos != ctx->filePos)
-			fprintf(stderr, "Warning: ftell mismatch with filePos\n");
+		{
+			fprintf(stderr, "Warning: ftell mismatch with filePos - filePos used\n");
+			pos = ctx->filePos;
+		}
 	}
 	else
 		pos = ctx->filePos;
diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c
index 9f46863819bac1fa1f2fd38cbe8a47be73411370..a0d9a2dc5f4a0aba36f4ad7ab75a9a8de51d6e9d 100644
--- a/src/bin/pg_dump/pg_backup_db.c
+++ b/src/bin/pg_dump/pg_backup_db.c
@@ -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.17 2001/03/23 04:49:55 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.18 2001/04/25 07:03:19 pjw Exp $
  *
  * NOTES
  *
@@ -114,17 +114,36 @@ _prompt_for_password(char *username, char *password)
 	fprintf(stderr, "\n\n");
 }
 
+static int
+_parse_version(ArchiveHandle *AH, const char* versionString)
+{
+	int			cnt;
+	int			vmaj, vmin, vrev;
+
+	cnt = sscanf(versionString, "%d.%d.%d", &vmaj, &vmin, &vrev);
+
+	if (cnt < 2)
+	{
+		die_horribly(AH, "Unable to parse version string: %s\n", versionString);
+	}
+
+	if (cnt == 2)
+		vrev = 0;
+
+	return (100 * vmaj + vmin) * 100 + vrev;
+}
 
 static void
 _check_database_version(ArchiveHandle *AH, bool ignoreVersion)
 {
 	PGresult   *res;
-	double		myversion;
+	int			myversion;
 	const char *remoteversion_str;
-	double		remoteversion;
+	int			remoteversion;
 	PGconn	   *conn = AH->connection;
 
-	myversion = strtod(PG_VERSION, NULL);
+	myversion = _parse_version(AH, PG_VERSION);
+
 	res = PQexec(conn, "SELECT version()");
 	if (!res ||
 		PQresultStatus(res) != PGRES_TUPLES_OK ||
@@ -134,8 +153,14 @@ _check_database_version(ArchiveHandle *AH, bool ignoreVersion)
 			  "Explanation from backend: '%s'.\n", PQerrorMessage(conn));
 
 	remoteversion_str = PQgetvalue(res, 0, 0);
-	remoteversion = strtod(remoteversion_str + 11, NULL);
-	if (myversion != remoteversion)
+	remoteversion = _parse_version(AH, remoteversion_str + 11);
+
+	PQclear(res);
+
+	AH->public.remoteVersion = remoteversion;
+
+	if (myversion != remoteversion 
+		&& (remoteversion < AH->public.minRemoteVersion || remoteversion > AH->public.maxRemoteVersion) )
 	{
 		fprintf(stderr, "Database version: %s\n%s version: %s\n",
 				remoteversion_str, progname, PG_VERSION);
@@ -145,7 +170,6 @@ _check_database_version(ArchiveHandle *AH, bool ignoreVersion)
 			die_horribly(AH, "Aborting because of version mismatch.\n"
 						 "Use --ignore-version if you think it's safe to proceed anyway.\n");
 	}
-	PQclear(res);
 }
 
 /*
diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c
index 93afbefb5482d31ac58efb1fa5138f59bec89b99..8c67141cd3509f0bec4a7683f3415d545f11e20a 100644
--- a/src/bin/pg_dump/pg_backup_tar.c
+++ b/src/bin/pg_dump/pg_backup_tar.c
@@ -16,7 +16,7 @@
  *
  *
  * IDENTIFICATION
- *		$Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_tar.c,v 1.14 2001/04/14 13:11:03 pjw Exp $
+ *		$Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_tar.c,v 1.15 2001/04/25 07:03:19 pjw Exp $
  *
  * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
  *
@@ -834,6 +834,7 @@ _CloseArchive(ArchiveHandle *AH)
 		ropt->dropSchema = 1;
 		ropt->compression = 0;
 		ropt->superuser = PQuser(AH->connection);
+		ropt->suppressDumpWarnings = true;
 
 		savVerbose = AH->public.verbose;
 		AH->public.verbose = 0;
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 3d8eb7b1ff069bad1d9ca3db3d1a10952b0ebe29..b06ee7f58bfbec6b4a43867231b362603e156305 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.204 2001/04/23 23:36:33 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.205 2001/04/25 07:03:19 pjw Exp $
  *
  * Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
  *
@@ -185,7 +185,8 @@ static void formatStringLiteral(PQExpBuffer buf, const char *str, const formatLi
 static void clearTableInfo(TableInfo *, int);
 static void dumpOneFunc(Archive *fout, FuncInfo *finfo, int i,
 			TypeInfo *tinfo, int numTypes);
-static Oid	findLastBuiltinOid(const char *);
+static Oid	findLastBuiltinOid_V71(const char *);
+static Oid	findLastBuiltinOid_V70(void);
 static void setMaxOid(Archive *fout);
 
 static void AddAcl(char *aclbuf, const char *keyword);
@@ -495,8 +496,13 @@ dumpClasses_dumpData(Archive *fout, char *oid, void *dctxv)
 	int			tuple;
 	int			field;
 
-	appendPQExpBuffer(q, "SELECT * FROM ONLY %s",
-					  fmtId(classname, force_quotes));
+	if (fout->remoteVersion >= 70100)
+	{
+		appendPQExpBuffer(q, "SELECT * FROM ONLY %s", fmtId(classname, force_quotes));
+	} else {
+		appendPQExpBuffer(q, "SELECT * FROM %s", fmtId(classname, force_quotes));
+	}
+
 	res = PQexec(g_conn, q->data);
 	if (!res ||
 		PQresultStatus(res) != PGRES_TUPLES_OK)
@@ -1037,8 +1043,10 @@ main(int argc, char **argv)
 
 	/*
 	 * Open the database using the Archiver, so it knows about it. Errors
-	 * mean death
+	 * mean death. Accept 7.0 & 7.1 database versions.
 	 */
+	g_fout->minRemoteVersion = 70000;
+	g_fout->maxRemoteVersion = 70199;
 	g_conn = ConnectDatabase(g_fout, dbname, pghost, pgport, use_password, ignore_version);
 
 	/*
@@ -1061,7 +1069,10 @@ main(int argc, char **argv)
 		PQclear(res);
 	}
 
-	g_last_builtin_oid = findLastBuiltinOid(dbname);
+	if (g_fout->remoteVersion >= 70100)
+		g_last_builtin_oid = findLastBuiltinOid_V71(dbname);
+	else
+		g_last_builtin_oid = findLastBuiltinOid_V70();
 
 	/* Dump the database definition */
 	if (!dataOnly)
@@ -1120,6 +1131,8 @@ main(int argc, char **argv)
 		else
 			ropt->compression = compressLevel;
 
+		ropt->suppressDumpWarnings = true; /* We've already shown them */
+
 		RestoreArchive(g_fout, ropt);
 	}
 
@@ -1210,7 +1223,12 @@ dumpBlobs(Archive *AH, char *junkOid, void *junkVal)
 		fprintf(stderr, "%s saving BLOBs\n", g_comment_start);
 
 	/* Cursor to get all BLOB tables */
-	appendPQExpBuffer(oidQry, "Declare blobOid Cursor for SELECT DISTINCT loid FROM pg_largeobject");
+	if (AH->remoteVersion >= 70100)
+	{
+		appendPQExpBuffer(oidQry, "Declare blobOid Cursor for SELECT DISTINCT loid FROM pg_largeobject");
+	} else {
+		appendPQExpBuffer(oidQry, "Declare blobOid Cursor for SELECT oid from pg_class where relkind = 'l'");
+	}
 
 	res = PQexec(g_conn, oidQry->data);
 	if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
@@ -1320,12 +1338,22 @@ getTypes(int *numTypes)
 	 * we filter out the built-in types when we dump out the types
 	 */
 
-	appendPQExpBuffer(query, "SELECT pg_type.oid, typowner, typname, typlen, typprtlen, "
-		  "typinput, typoutput, typreceive, typsend, typelem, typdelim, "
-					  "typdefault, typrelid, typbyval, "
-	"(select usename from pg_user where typowner = usesysid) as usename, "
-					  "format_type(pg_type.oid, NULL) as typedefn "
-					  "from pg_type");
+	if (g_fout->remoteVersion < 70100)
+	{
+		appendPQExpBuffer(query, "SELECT pg_type.oid, typowner, typname, typlen, typprtlen, "
+						"typinput, typoutput, typreceive, typsend, typelem, typdelim, "
+						"typdefault, typrelid, typbyval, "
+						"(select usename from pg_user where typowner = usesysid) as usename, "
+						"typname as typedefn "
+						"from pg_type");
+	} else {
+		appendPQExpBuffer(query, "SELECT pg_type.oid, typowner, typname, typlen, typprtlen, "
+						"typinput, typoutput, typreceive, typsend, typelem, typdelim, "
+						"typdefault, typrelid, typbyval, "
+						"(select usename from pg_user where typowner = usesysid) as usename, "
+						"format_type(pg_type.oid, NULL) as typedefn "
+						"from pg_type");
+	}
 
 	res = PQexec(g_conn, query->data);
 	if (!res ||
@@ -1787,15 +1815,26 @@ getAggregates(int *numAggs)
 	int			i_aggbasetype;
 	int			i_agginitval;
 	int			i_usename;
+	int			i_convertok;
 
 	/* find all user-defined aggregates */
 
-	appendPQExpBuffer(query,
-					  "SELECT pg_aggregate.oid, aggname, aggtransfn, "
-					  "aggfinalfn, aggtranstype, aggbasetype, "
-					  "agginitval, "
-	"(select usename from pg_user where aggowner = usesysid) as usename "
-					  "from pg_aggregate");
+	if (g_fout->remoteVersion < 70100)
+	{
+		appendPQExpBuffer(query, "SELECT pg_aggregate.oid, aggname, aggtransfn1 as aggtransfn, "
+			"aggfinalfn, aggtranstype1 as aggtranstype, aggbasetype, "
+			"agginitval1 as agginitval, "
+			"(aggtransfn2 = 0 and aggtranstype2 = 0 and agginitval2 is null) as convertok, "
+			"(select usename from pg_user where aggowner = usesysid) as usename "
+			"from pg_aggregate");
+	} else {
+		appendPQExpBuffer(query, "SELECT pg_aggregate.oid, aggname, aggtransfn, "
+			"aggfinalfn, aggtranstype, aggbasetype, "
+			"agginitval, "
+			"'t'::boolean as convertok, "
+			"(select usename from pg_user where aggowner = usesysid) as usename "
+			"from pg_aggregate");
+	}
 
 	res = PQexec(g_conn, query->data);
 	if (!res ||
@@ -1819,6 +1858,7 @@ getAggregates(int *numAggs)
 	i_aggbasetype = PQfnumber(res, "aggbasetype");
 	i_agginitval = PQfnumber(res, "agginitval");
 	i_usename = PQfnumber(res, "usename");
+	i_convertok = PQfnumber(res, "convertok");
 
 	for (i = 0; i < ntups; i++)
 	{
@@ -1834,6 +1874,8 @@ getAggregates(int *numAggs)
 			fprintf(stderr, "WARNING: owner of aggregate '%s' appears to be invalid\n",
 					agginfo[i].aggname);
 
+		agginfo[i].convertok = (PQgetvalue(res, i, i_convertok)[0] == 't');
+
 	}
 
 	PQclear(res);
@@ -1874,14 +1916,26 @@ getFuncs(int *numFuncs)
 
 	/* find all user-defined funcs */
 
-	appendPQExpBuffer(query,
+	if (g_fout->remoteVersion < 70100)
+	{
+		appendPQExpBuffer(query,
+		   "SELECT pg_proc.oid, proname, prolang, pronargs, prorettype, "
+					  "proretset, proargtypes, prosrc, probin, "
+				"(select usename from pg_user where proowner = usesysid) as usename, "
+				"proiscachable, 't'::boolean as proisstrict "
+				"from pg_proc "
+				"where pg_proc.oid > '%u'::oid",
+					  g_last_builtin_oid);
+	} else {
+		appendPQExpBuffer(query,
 		   "SELECT pg_proc.oid, proname, prolang, pronargs, prorettype, "
 					  "proretset, proargtypes, prosrc, probin, "
-	"(select usename from pg_user where proowner = usesysid) as usename, "
-					  "proiscachable, proisstrict "
-					  "from pg_proc "
-					  "where pg_proc.oid > '%u'::oid",
+				"(select usename from pg_user where proowner = usesysid) as usename, "
+				"proiscachable, proisstrict "
+				"from pg_proc "
+				"where pg_proc.oid > '%u'::oid",
 					  g_last_builtin_oid);
+	}
 
 	res = PQexec(g_conn, query->data);
 	if (!res ||
@@ -1935,7 +1989,7 @@ getFuncs(int *numFuncs)
 
 		if (finfo[i].nargs < 0 || finfo[i].nargs > FUNC_MAX_ARGS)
 		{
-			fprintf(stderr, "failed sanity check: %s has %d args\n",
+			fprintf(stderr, "getFuncs(): failed sanity check: %s has %d args\n",
 					finfo[i].proname, finfo[i].nargs);
 			exit(1);
 		}
@@ -2217,12 +2271,32 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
 			int			n;
 
 			resetPQExpBuffer(query);
-			appendPQExpBuffer(query,
+			if (g_fout->remoteVersion < 70100) 
+			{
+				/* Fake the LOJ from below */
+				appendPQExpBuffer(query,
+							  "  SELECT c.relname "
+							  "    FROM pg_index i, pg_class c "
+							  "    WHERE     i.indrelid = %s"
+							  "        AND   i.indisprimary "
+							  "        AND   c.oid = i.indexrelid"
+							  " UNION ALL "
+							  "  SELECT NULL "
+							  "    FROM pg_index i "
+							  "    WHERE i.indrelid = %s"
+							  "    AND   i.indisprimary "
+							  "    And NOT Exists(Select * From pg_class c Where c.oid = i.indexrelid)",
+							  tblinfo[i].oid, tblinfo[i].oid);
+
+			} else {
+				appendPQExpBuffer(query,
 							  "SELECT c.relname "
 							  "FROM pg_index i LEFT OUTER JOIN pg_class c ON c.oid = i.indexrelid "
 							  "WHERE i.indrelid = %s"
 							  "AND   i.indisprimary ",
 							  tblinfo[i].oid);
+			}
+
 			res2 = PQexec(g_conn, query->data);
 			if (!res2 || PQresultStatus(res2) != PGRES_TUPLES_OK)
 			{
@@ -2275,6 +2349,8 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
 						i_tgisconstraint,
 						i_tgconstrname,
 						i_tgdeferrable,
+						i_tgconstrrelid,
+						i_tgconstrrelname,
 						i_tginitdeferred;
 			int			ntups2;
 			int			i2;
@@ -2286,7 +2362,12 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
 						g_comment_end);
 
 			resetPQExpBuffer(query);
-			appendPQExpBuffer(query, "SELECT tgname, tgfoid, tgtype, tgnargs, tgargs, tgisconstraint, tgconstrname, tgdeferrable, tginitdeferred, oid "
+			appendPQExpBuffer(query, 
+								"SELECT tgname, tgfoid, tgtype, tgnargs, tgargs, "
+								"tgisconstraint, tgconstrname, tgdeferrable, "
+								"tgconstrrelid, tginitdeferred, oid, "
+								"(select relname from pg_class where oid = tgconstrrelid) "
+								"		as tgconstrrelname "
 							  "from pg_trigger "
 							  "where tgrelid = '%s'::oid ",
 							  tblinfo[i].oid);
@@ -2314,6 +2395,8 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
 			i_tgisconstraint = PQfnumber(res2, "tgisconstraint");
 			i_tgconstrname = PQfnumber(res2, "tgconstrname");
 			i_tgdeferrable = PQfnumber(res2, "tgdeferrable");
+			i_tgconstrrelid = PQfnumber(res2, "tgconstrrelid");
+			i_tgconstrrelname = PQfnumber(res2, "tgconstrrelname");
 			i_tginitdeferred = PQfnumber(res2, "tginitdeferred");
 
 			tblinfo[i].triggers = (TrigInfo *) malloc(ntups2 * sizeof(TrigInfo));
@@ -2328,9 +2411,13 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
 				int			tgisconstraint;
 				int			tgdeferrable;
 				int			tginitdeferred;
+				char	   *tgconstrrelid;
+				char	   *tgname;
 				const char *p;
 				int			findx;
 
+				tgname = PQgetvalue(res2, i2, i_tgname);
+
 				if (strcmp(PQgetvalue(res2, i2, i_tgisconstraint), "f") == 0)
 					tgisconstraint = 0;
 				else
@@ -2376,7 +2463,7 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
 					if (!r || PQresultStatus(r) != PGRES_TUPLES_OK)
 					{
 						fprintf(stderr, "getTables(): SELECT (funcname) failed for trigger %s.  Explanation from backend: '%s'.\n",
-								PQgetvalue(res2, i2, i_tgname), PQerrorMessage(g_conn));
+								tgname, PQerrorMessage(g_conn));
 						exit_nicely(g_conn);
 					}
 
@@ -2385,7 +2472,7 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
 					if (numFuncs != 1)
 					{
 						fprintf(stderr, "getTables(): SELECT (funcname) for trigger %s returned %d tuples. Expected 1.\n",
-								PQgetvalue(res2, i2, i_tgname), numFuncs);
+								tgname, numFuncs);
 						exit_nicely(g_conn);
 					}
 
@@ -2395,9 +2482,7 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
 				else
 					tgfunc = strdup(finfo[findx].proname);
 
-				appendPQExpBuffer(delqry, "DROP TRIGGER %s ",
-								  fmtId(PQgetvalue(res2, i2, i_tgname),
-										force_quotes));
+				appendPQExpBuffer(delqry, "DROP TRIGGER %s ", fmtId(tgname, force_quotes));
 				appendPQExpBuffer(delqry, "ON %s;\n",
 								fmtId(tblinfo[i].relname, force_quotes));
 
@@ -2410,7 +2495,7 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
 				else
 				{
 					appendPQExpBuffer(query, "CREATE TRIGGER ");
-					appendPQExpBuffer(query, fmtId(PQgetvalue(res2, i2, i_tgname), force_quotes));
+					appendPQExpBuffer(query, fmtId(tgname, force_quotes));
 				}
 				appendPQExpBufferChar(query, ' ');
 				/* Trigger type */
@@ -2443,6 +2528,21 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
 
 				if (tgisconstraint)
 				{
+					tgconstrrelid = PQgetvalue(res2, i2, i_tgconstrrelid);
+
+					if (strcmp(tgconstrrelid, "0") != 0) {
+
+						if (PQgetisnull(res2, i2, i_tgconstrrelname))
+            			{
+                			fprintf(stderr, "getTables(): SELECT produced NULL referenced table name "
+											"for trigger '%s' on relation '%s' (oid was %s).\n",
+											tgname, tblinfo[i].relname, tgconstrrelid);
+                			exit_nicely(g_conn);
+            			}
+
+						appendPQExpBuffer(query, " FROM %s", 
+										fmtId(PQgetvalue(res2, i2, i_tgconstrrelname), force_quotes));
+					}
 					if (!tgdeferrable)
 						appendPQExpBuffer(query, " NOT");
 					appendPQExpBuffer(query, " DEFERRABLE INITIALLY ");
@@ -2469,7 +2569,7 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
 									"string (%s) for trigger '%s'\n",
 									tblinfo[i].relname,
 									PQgetvalue(res2, i2, i_tgargs),
-									PQgetvalue(res2, i2, i_tgname));
+									tgname);
 							exit_nicely(g_conn);
 						}
 						p++;
@@ -2501,12 +2601,12 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
 
 				resetPQExpBuffer(query);
 				appendPQExpBuffer(query, "TRIGGER %s ",
-					fmtId(PQgetvalue(res2, i2, i_tgname), force_quotes));
+					fmtId(tgname, force_quotes));
 				appendPQExpBuffer(query, "ON %s",
 								fmtId(tblinfo[i].relname, force_quotes));
 				tblinfo[i].triggers[i2].tgcomment = strdup(query->data);
 				tblinfo[i].triggers[i2].oid = strdup(PQgetvalue(res2, i2, i_tgoid));
-				tblinfo[i].triggers[i2].tgname = strdup(fmtId(PQgetvalue(res2, i2, i_tgname), false));
+				tblinfo[i].triggers[i2].tgname = strdup(fmtId(tgname, false));
 				tblinfo[i].triggers[i2].tgdel = strdup(delqry->data);
 
 				if (tgfunc)
@@ -2624,12 +2724,35 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
 					g_comment_end);
 
 		resetPQExpBuffer(q);
-		appendPQExpBuffer(q, "SELECT a.oid as attoid, a.attnum, a.attname, t.typname, a.atttypmod, "
-						  "a.attnotnull, a.atthasdef, format_type(a.atttypid, a.atttypmod) as atttypedefn "
-						  "from pg_attribute a LEFT OUTER JOIN pg_type t ON a.atttypid = t.oid "
-						  "where a.attrelid = '%s'::oid "
-						  "and a.attnum > 0 order by attnum",
-						  tblinfo[i].oid);
+
+		if (g_fout->remoteVersion < 70100)
+		{
+			/* Fake the LOJ below */
+			appendPQExpBuffer(q, 
+						"  SELECT a.oid as attoid, a.attnum, a.attname, t.typname, a.atttypmod, "
+						"        a.attnotnull, a.atthasdef, NULL as atttypedefn "
+						"    from pg_attribute a, pg_type t "
+						"    where a.attrelid = '%s'::oid "
+						"        and a.attnum > 0 "
+						"        and a.atttypid = t.oid "
+						" UNION ALL SELECT a.oid as attoid, a.attnum, a.attname, NULL as typname, a.atttypmod, "
+						"        a.attnotnull, a.atthasdef, NULL as atttypedefn "
+						"    from pg_attribute a "
+						"    where a.attrelid = '%s'::oid "
+						"        and a.attnum > 0 "
+						"        and Not Exists(Select * From pg_type t where a.atttypid = t.oid)"
+						"    order by attnum",
+						tblinfo[i].oid, tblinfo[i].oid);
+
+		} else {
+			appendPQExpBuffer(q, "SELECT a.oid as attoid, a.attnum, a.attname, t.typname, a.atttypmod, "
+								"a.attnotnull, a.atthasdef, format_type(a.atttypid, a.atttypmod) as atttypedefn "
+								"from pg_attribute a LEFT OUTER JOIN pg_type t ON a.atttypid = t.oid "
+								"where a.attrelid = '%s'::oid "
+								"and a.attnum > 0 order by attnum",
+								tblinfo[i].oid);
+		}
+
 		res = PQexec(g_conn, q->data);
 		if (!res ||
 			PQresultStatus(res) != PGRES_TUPLES_OK)
@@ -2778,6 +2901,9 @@ getIndices(int *numIndices)
 					  "and t2.relname !~ '^pg_' ",
 					  g_last_builtin_oid);
 
+	if (g_fout->remoteVersion < 70100)
+		appendPQExpBuffer(query, " and t2.relkind != 'l'");
+
 	res = PQexec(g_conn, query->data);
 	if (!res ||
 		PQresultStatus(res) != PGRES_TUPLES_OK)
@@ -3499,9 +3625,13 @@ dumpAggs(Archive *fout, AggInfo *agginfo, int numAggs,
 		 TypeInfo *tinfo, int numTypes)
 {
 #define AGG_NOTICE(arg) {\
-		fprintf(stderr, "Notice: aggregate \"%s\"(oid %s) is not dumped.\n",agginfo[i].aggname, agginfo[i].oid);\
-	fprintf(stderr, "Reason: " CppAsString(arg) );\
-	fprintf (stderr, " (oid %s) not found.\n",agginfo[i].arg);\
+		resetPQExpBuffer(q);\
+		appendPQExpBuffer(q, "-- Notice: aggregate \"%s\"(oid %s) is not dumped.\n",agginfo[i].aggname, agginfo[i].oid);\
+		appendPQExpBuffer(q, "-- Reason: " CppAsString(arg) );\
+		appendPQExpBuffer(q, " (oid %s) not found.\n",agginfo[i].arg);\
+		fprintf(stderr, q->data);\
+		ArchiveEntry(fout, agginfo[i].oid, aggSig->data, "WARNING", NULL,\
+					q->data, "" /* Del */, "", agginfo[i].usename, NULL, NULL);\
 	}
 
 	int			i;
@@ -3517,9 +3647,25 @@ dumpAggs(Archive *fout, AggInfo *agginfo, int numAggs,
 		resetPQExpBuffer(details);
 
 		/* skip all the builtin oids */
-		if (atooid(agginfo[i].oid) <= g_last_builtin_oid)
+		if ( oidle( atooid(agginfo[i].oid), g_last_builtin_oid) )
 			continue;
 
+		resetPQExpBuffer(aggSig);
+		appendPQExpBuffer(aggSig, "%s(%s)", agginfo[i].aggname,
+						  findTypeByOid(tinfo, numTypes, agginfo[i].aggbasetype, zeroAsOpaque + useBaseTypeName));
+
+		if (!agginfo[i].convertok)
+		{
+			resetPQExpBuffer(q);
+			appendPQExpBuffer(q, "-- WARNING: Aggregate %s could not be dumped correctly for this database version - ignored\n",
+									aggSig->data);
+			fprintf(stderr, q->data);
+
+			ArchiveEntry(fout, agginfo[i].oid, aggSig->data, "WARNING", NULL,
+					q->data, "" /* Del */, "", agginfo[i].usename, NULL, NULL);
+			continue;
+		}
+
 		name = findTypeByOid(tinfo, numTypes, agginfo[i].aggbasetype, zeroAsAny + useBaseTypeName);
 		if (name == NULL)
 		{
@@ -3548,10 +3694,6 @@ dumpAggs(Archive *fout, AggInfo *agginfo, int numAggs,
 			appendPQExpBuffer(details, ", FINALFUNC = %s",
 							  agginfo[i].aggfinalfn);
 
-		resetPQExpBuffer(aggSig);
-		appendPQExpBuffer(aggSig, "%s %s", agginfo[i].aggname,
-						  findTypeByOid(tinfo, numTypes, agginfo[i].aggbasetype, zeroAsOpaque + useBaseTypeName));
-
 		resetPQExpBuffer(delq);
 		appendPQExpBuffer(delq, "DROP AGGREGATE %s;\n", aggSig->data);
 
@@ -3737,6 +3879,61 @@ dumpACL(Archive *fout, TableInfo tbinfo)
 
 }
 
+static void
+_dumpTableAttr70(Archive *fout, TableInfo *tblinfo, int i, int j, PQExpBuffer q)
+{
+	int32				tmp_typmod;
+	int					precision;
+	int					scale;
+
+	/* Show lengths on bpchar and varchar */
+	if (!strcmp(tblinfo[i].typnames[j], "bpchar"))
+	{
+		int			len = (tblinfo[i].atttypmod[j] - VARHDRSZ);
+
+		appendPQExpBuffer(q, "character");
+		if (len > 1)
+			appendPQExpBuffer(q, "(%d)",
+					 tblinfo[i].atttypmod[j] - VARHDRSZ);
+	}
+	else if (!strcmp(tblinfo[i].typnames[j], "varchar"))
+	{
+		appendPQExpBuffer(q, "character varying");
+		if (tblinfo[i].atttypmod[j] != -1)
+		{
+			appendPQExpBuffer(q, "(%d)",
+					 tblinfo[i].atttypmod[j] - VARHDRSZ);
+		}
+	}
+	else if (!strcmp(tblinfo[i].typnames[j], "numeric"))
+	{
+		appendPQExpBuffer(q, "numeric");
+		if (tblinfo[i].atttypmod[j] != -1)
+		{
+			tmp_typmod = tblinfo[i].atttypmod[j] - VARHDRSZ;
+			precision = (tmp_typmod >> 16) & 0xffff;
+			scale = tmp_typmod & 0xffff;
+			appendPQExpBuffer(q, "(%d,%d)",
+							  precision, scale);
+		}
+	}
+
+	/*
+	 * char is an internal single-byte data type; Let's
+	 * make sure we force it through with quotes. - thomas
+	 * 1998-12-13
+	 */
+	else if (!strcmp(tblinfo[i].typnames[j], "char"))
+	{
+		appendPQExpBuffer(q, "%s",
+					fmtId(tblinfo[i].typnames[j], true));
+	}
+	else
+	{
+		appendPQExpBuffer(q, "%s",
+				   fmtId(tblinfo[i].typnames[j], false));
+	}
+}
 
 /*
  * dumpTables:
@@ -3830,9 +4027,14 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
 							appendPQExpBuffer(q, ",\n\t");
 
 						/* Attr name & type */
-						appendPQExpBuffer(q, "%s %s",
-							 fmtId(tblinfo[i].attnames[j], force_quotes),
-										  tblinfo[i].atttypedefns[j]);
+						appendPQExpBuffer(q, "%s ", fmtId(tblinfo[i].attnames[j], force_quotes));
+
+						if (g_fout->remoteVersion >= 70100)
+						{
+							appendPQExpBuffer(q, "%s", tblinfo[i].atttypedefns[j]);
+						} else {
+							_dumpTableAttr70(fout, tblinfo, i, j, q);
+						}
 
 						/* Default value */
 						if (tblinfo[i].adef_expr[j] != NULL && tblinfo[i].inhAttrDef[j] == 0)
@@ -4033,7 +4235,7 @@ dumpIndices(Archive *fout, IndInfo *indinfo, int numIndices,
 								   indinfo[i].indrelname);
 		if (tableInd < 0)
 		{
-			fprintf(stderr, "failed sanity check, table %s was not found\n",
+			fprintf(stderr, "dumpIndices(): failed sanity check, table %s was not found\n",
 					indinfo[i].indrelname);
 			exit(1);
 		}
@@ -4357,7 +4559,7 @@ setMaxOid(Archive *fout)
  */
 
 static Oid
-findLastBuiltinOid(const char *dbname)
+findLastBuiltinOid_V71(const char *dbname)
 {
 	PGresult   *res;
 	int			ntups;
@@ -4389,11 +4591,51 @@ findLastBuiltinOid(const char *dbname)
 		fprintf(stderr, "There is more than one entry for this database in the 'pg_database' table\n");
 		exit_nicely(g_conn);
 	}
-	last_oid = atoi(PQgetvalue(res, 0, PQfnumber(res, "datlastsysoid")));
+	last_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "datlastsysoid")));
 	PQclear(res);
 	return last_oid;
 }
 
+/*
+ * findLastBuiltInOid -
+ * find the last built in oid
+ * we do this by looking up the oid of 'template1' in pg_database,
+ * this is probably not foolproof but comes close
+*/
+
+static Oid 
+findLastBuiltinOid_V70(void)
+{
+	PGresult   *res;
+	int			ntups;
+	int			last_oid;
+
+	res = PQexec(g_conn,
+			  "SELECT oid from pg_database where datname = 'template1'");
+	if (res == NULL ||
+		PQresultStatus(res) != PGRES_TUPLES_OK)
+	{
+		fprintf(stderr, "pg_dump error in finding the template1 database.");
+		fprintf(stderr, "Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
+		exit_nicely(g_conn);
+	}
+	ntups = PQntuples(res);
+	if (ntups < 1)
+	{
+		fprintf(stderr, "pg_dump: couldn't find the template1 database.\n");
+		fprintf(stderr, "There is no 'template1' entry in the 'pg_database' table.\n");
+		exit_nicely(g_conn);
+	}
+	if (ntups > 1)
+	{
+		fprintf(stderr, "pg_dump: found more than one template1 database.\n");
+		fprintf(stderr, "There is more than one 'template1' entry in the 'pg_database' table\n");
+		exit_nicely(g_conn);
+	}
+	last_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "oid")));
+	PQclear(res);
+	return last_oid;
+}
 
 static void
 dumpSequence(Archive *fout, TableInfo tbinfo, const bool schemaOnly, const bool dataOnly)
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index b10d40876d2860b5eb61dfa031e4c68548a0c1e7..8e5db6015cb5d465ce13828b91e7635663cf54b2 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -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.62 2001/04/14 13:11:03 pjw Exp $
+ * $Id: pg_dump.h,v 1.63 2001/04/25 07:03:20 pjw Exp $
  *
  * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
  *
@@ -159,6 +159,7 @@ typedef struct _aggInfo
 	char	   *aggbasetype;
 	char	   *agginitval;
 	char	   *usename;
+	int		   convertok;		/* Flag to indicate of version convertsion is OK */
 } AggInfo;
 
 typedef struct _oprInfo