diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
index 4711a769763ee2883ea7623f5d1c373576d772a2..a466dafc5da59b50a36a07d47cbbd36c3d3e2ec8 100644
--- a/src/bin/pg_dump/common.c
+++ b/src/bin/pg_dump/common.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.48 2000/12/03 20:45:37 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.49 2001/01/12 15:41:29 pjw Exp $
  *
  * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
  *
@@ -270,12 +270,14 @@ dumpSchema(Archive  *fout,
 	int			numInherits;
 	int			numAggregates;
 	int			numOperators;
+	int			numIndices;
 	TypeInfo   *tinfo = NULL;
 	FuncInfo   *finfo = NULL;
 	AggInfo    *agginfo = NULL;
 	TableInfo  *tblinfo = NULL;
 	InhInfo    *inhinfo = NULL;
 	OprInfo    *oprinfo = NULL;
+	IndInfo    *indinfo = NULL;
 
 	if (g_verbose)
 		fprintf(stderr, "%s reading user-defined types %s\n",
@@ -302,6 +304,11 @@ dumpSchema(Archive  *fout,
 				g_comment_start, g_comment_end);
 	tblinfo = getTables(&numTables, finfo, numFuncs);
 
+	if (g_verbose)
+		fprintf(stderr, "%s reading indices information %s\n",
+				g_comment_start, g_comment_end);
+	indinfo = getIndices(&numIndices);
+
 	if (g_verbose)
 		fprintf(stderr, "%s reading table inheritance information %s\n",
 				g_comment_start, g_comment_end);
@@ -336,9 +343,18 @@ dumpSchema(Archive  *fout,
 	if (g_verbose)
 		fprintf(stderr, "%s dumping out tables %s\n",
 				g_comment_start, g_comment_end);
-	dumpTables(fout, tblinfo, numTables, inhinfo, numInherits,
+
+	dumpTables(fout, tblinfo, numTables, indinfo, numIndices, inhinfo, numInherits,
 			   tinfo, numTypes, tablename, aclsSkip, oids, schemaOnly, dataOnly);
 
+	if (fout && !dataOnly)
+	{
+		if (g_verbose)
+			fprintf(stderr, "%s dumping out indices %s\n",
+					g_comment_start, g_comment_end);
+		dumpIndices(fout, indinfo, numIndices, tblinfo, numTables, tablename);
+	}
+
 	if (!tablename && !dataOnly)
 	{
 		if (g_verbose)
@@ -377,35 +393,8 @@ dumpSchema(Archive  *fout,
 	clearTypeInfo(tinfo, numTypes);
 	clearFuncInfo(finfo, numFuncs);
 	clearInhInfo(inhinfo, numInherits);
-	return tblinfo;
-}
-
-/*
- * dumpSchemaIdx:
- *	  dump indexes at the end for performance
- *
- */
-
-extern void
-dumpSchemaIdx(Archive *fout, const char *tablename,
-			  TableInfo *tblinfo, int numTables)
-{
-	int			numIndices;
-	IndInfo    *indinfo;
-
-	if (g_verbose)
-		fprintf(stderr, "%s reading indices information %s\n",
-				g_comment_start, g_comment_end);
-	indinfo = getIndices(&numIndices);
-
-	if (fout)
-	{
-		if (g_verbose)
-			fprintf(stderr, "%s dumping out indices %s\n",
-					g_comment_start, g_comment_end);
-		dumpIndices(fout, indinfo, numIndices, tblinfo, numTables, tablename);
-	}
 	clearIndInfo(indinfo, numIndices);
+	return tblinfo;
 }
 
 /* flagInhAttrs -
diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h
index 9a9c2e78a84a42b000a0ab37bb8e34ddf23b0ae7..0808af32c81adcbb925fa02ded4a3576f8065f79 100644
--- a/src/bin/pg_dump/pg_backup_archiver.h
+++ b/src/bin/pg_dump/pg_backup_archiver.h
@@ -62,7 +62,7 @@ typedef z_stream *z_streamp;
 
 #define K_VERS_MAJOR 1
 #define K_VERS_MINOR 4 
-#define K_VERS_REV 23 
+#define K_VERS_REV 24 
 
 /* Data block types */
 #define BLK_DATA 1
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index ba10354b6d656d5ad0c9a1f2e642622e69beb41b..a383ec7dd6ec538bf2ae275b3177880c50299b75 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.186 2001/01/12 04:32:07 pjw Exp $
+ *	  $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.187 2001/01/12 15:41:29 pjw Exp $
  *
  * Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
  *
@@ -155,6 +155,7 @@ static char *GetPrivileges(const char *s);
 
 static int dumpBlobs(Archive *AH, char*, void*);
 static int dumpDatabase(Archive *AH);
+static PQExpBuffer getPKconstraint(TableInfo *tblInfo, IndInfo *indInfo);
 
 extern char *optarg;
 extern int	optind,
@@ -1027,7 +1028,6 @@ main(int argc, char **argv)
 	if (!dataOnly)				/* dump indexes and triggers at the end
 								 * for performance */
 	{
-		dumpSchemaIdx(g_fout, tablename, tblinfo, numTables);
 		dumpTriggers(g_fout, tablename, tblinfo, numTables);
 		dumpRules(g_fout, tablename, tblinfo, numTables);
 	}
@@ -1038,6 +1038,7 @@ main(int argc, char **argv)
 	MoveToEnd(g_fout, "TABLE DATA");
 	MoveToEnd(g_fout, "BLOBS");
 	MoveToEnd(g_fout, "INDEX");
+	MoveToEnd(g_fout, "CONSTRAINT");
 	MoveToEnd(g_fout, "TRIGGER");
 	MoveToEnd(g_fout, "RULE");
 	MoveToEnd(g_fout, "SEQUENCE SET");
@@ -1568,8 +1569,6 @@ clearTableInfo(TableInfo *tblinfo, int numTables)
 			free(tblinfo[i].typnames);
 		if (tblinfo[i].notnull)
 			free(tblinfo[i].notnull);
-		if (tblinfo[i].primary_key)
-			free(tblinfo[i].primary_key);
 		if (tblinfo[i].primary_key_name)
 			free(tblinfo[i].primary_key_name);
 	}
@@ -1656,6 +1655,8 @@ clearIndInfo(IndInfo *ind, int numIndices)
 			free(ind[i].indproc);
 		if (ind[i].indisunique)
 			free(ind[i].indisunique);
+		if (ind[i].indisprimary)
+			free(ind[i].indisprimary);
 		for (a = 0; a < INDEX_MAX_KEYS; ++a)
 		{
 			if (ind[i].indkey[a])
@@ -2132,50 +2133,36 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
 		if (strcmp(PQgetvalue(res, i, i_relhasindex), "t") == 0)
 		{
 			PGresult   *res2;
-			char		str[INDEX_MAX_KEYS * (NAMEDATALEN * 2 + 4) + 1];
-			int			j;
 
 			resetPQExpBuffer(query);
 			appendPQExpBuffer(query,
-							  "SELECT a.attname "
-						   "FROM pg_index i, pg_class c, pg_attribute a "
-							  "WHERE i.indisprimary AND i.indrelid = %s "
-							  "  AND i.indexrelid = c.oid AND a.attnum > 0 AND a.attrelid = c.oid "
-							  "ORDER BY a.attnum ",
+							  "SELECT Oid FROM pg_index i WHERE i.indisprimary AND i.indrelid = %s ",
 							  tblinfo[i].oid);
 			res2 = PQexec(g_conn, query->data);
 			if (!res2 || PQresultStatus(res2) != PGRES_TUPLES_OK)
 			{
-				fprintf(stderr, "getTables(): SELECT (for PRIMARY KEY) failed.  Explanation from backend: %s",
+				fprintf(stderr, "getTables(): SELECT (for PRIMARY KEY) failed.  Explanation from backend: %s\n",
 						PQerrorMessage(g_conn));
 				exit_nicely(g_conn);
 			}
 
-			str[0] = '\0';
-			for (j = 0; j < PQntuples(res2); j++)
-			{
-				if (strlen(str) > 0)
-					strcat(str, ", ");
-				strcat(str, fmtId(PQgetvalue(res2, j, 0), force_quotes));
+			if (PQntuples(res2) > 1) {
+				fprintf(stderr, "getTables(): SELECT (for PRIMARY KEY) produced more than one row.\n");
+				exit_nicely(g_conn);
 			}
 
-			if (strlen(str) > 0)
-			{
-				tblinfo[i].primary_key = strdup(str);
-				if (tblinfo[i].primary_key == NULL)
-				{
-					perror("strdup");
-					exit(1);
-				}
+			if (PQntuples(res2) == 1) {
+				tblinfo[i].pkIndexOid = strdup(PQgetvalue(res2, 0, 0));
+			} else {
+				tblinfo[i].pkIndexOid = NULL;
 			}
-			else
-				tblinfo[i].primary_key = NULL;
+
 		}
 		else
-			tblinfo[i].primary_key = NULL;
+			tblinfo[i].pkIndexOid = NULL;
 
 		/* Get primary key name (if primary key exist) */
-		if (tblinfo[i].primary_key)
+		if (tblinfo[i].pkIndexOid != NULL)
 		{
 			PGresult   *res2;
 			int		   n;
@@ -2695,6 +2682,8 @@ getIndices(int *numIndices)
 	int			i_indclass;
 	int			i_indisunique;
 	int			i_indoid;
+	int			i_oid;
+	int			i_indisprimary;
 
 	/*
 	 * find all the user-defined indices. We do not handle partial
@@ -2706,13 +2695,13 @@ getIndices(int *numIndices)
 	 */
 
 	appendPQExpBuffer(query,
-					  "SELECT t1.oid as indoid, t1.relname as indexrelname, t2.relname as indrelname, "
+					  "SELECT i.oid, t1.oid as indoid, t1.relname as indexrelname, t2.relname as indrelname, "
 					  "i.indproc, i.indkey, i.indclass, "
-					  "a.amname as indamname, i.indisunique "
+					  "a.amname as indamname, i.indisunique, i.indisprimary "
 					"from pg_index i, pg_class t1, pg_class t2, pg_am a "
 				   "WHERE t1.oid = i.indexrelid and t2.oid = i.indrelid "
 					  "and t1.relam = a.oid and i.indexrelid > '%u'::oid "
-					  "and t2.relname !~ '^pg_' and not i.indisprimary",
+					  "and t2.relname !~ '^pg_' ",
 					  g_last_builtin_oid);
 
 	res = PQexec(g_conn, query->data);
@@ -2732,6 +2721,7 @@ getIndices(int *numIndices)
 
 	memset((char *) indinfo, 0, ntups * sizeof(IndInfo));
 
+	i_oid = PQfnumber(res, "oid");
 	i_indoid = PQfnumber(res, "indoid");
 	i_indexrelname = PQfnumber(res, "indexrelname");
 	i_indrelname = PQfnumber(res, "indrelname");
@@ -2740,9 +2730,11 @@ getIndices(int *numIndices)
 	i_indkey = PQfnumber(res, "indkey");
 	i_indclass = PQfnumber(res, "indclass");
 	i_indisunique = PQfnumber(res, "indisunique");
+	i_indisprimary = PQfnumber(res, "indisprimary");
 
 	for (i = 0; i < ntups; i++)
 	{
+		indinfo[i].oid = strdup(PQgetvalue(res, i, i_oid));
 		indinfo[i].indoid = strdup(PQgetvalue(res, i, i_indoid));
 		indinfo[i].indexrelname = strdup(PQgetvalue(res, i, i_indexrelname));
 		indinfo[i].indrelname = strdup(PQgetvalue(res, i, i_indrelname));
@@ -2755,6 +2747,7 @@ getIndices(int *numIndices)
 						  indinfo[i].indclass,
 						  INDEX_MAX_KEYS);
 		indinfo[i].indisunique = strdup(PQgetvalue(res, i, i_indisunique));
+		indinfo[i].indisprimary = strdup(PQgetvalue(res, i, i_indisprimary));
 	}
 	PQclear(res);
 	return indinfo;
@@ -3551,6 +3544,7 @@ dumpACL(Archive *fout, TableInfo tbinfo)
 
 void
 dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
+		   IndInfo *indinfo, int numIndices,
 		   InhInfo *inhinfo, int numInherits,
 		   TypeInfo *tinfo, int numTypes, const char *tablename,
 		   const bool aclsSkip, const bool oids,
@@ -3651,6 +3645,8 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
 					}
 				}
 
+
+
 				/* put the CONSTRAINTS inside the table def */
 				for (k = 0; k < tblinfo[i].ncheck; k++)
 				{
@@ -3661,17 +3657,36 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
 								  tblinfo[i].check_expr[k]);
 				}
 
-				/* PRIMARY KEY */
-				if (tblinfo[i].primary_key)
+				/* Primary Key */
+				if (tblinfo[i].pkIndexOid != NULL)
 				{
-					if (actual_atts + tblinfo[i].ncheck > 0)
+					PQExpBuffer	consDef;
+
+					/* Find the corresponding index */
+					for (k = 0; k < numIndices; k++)
+					{
+						if (strcmp(indinfo[k].oid, tblinfo[i].pkIndexOid) == 0) 
+							break;
+					}
+
+					if (k >= numIndices)
+					{
+						fprintf(stderr, "dumpTables(): failed sanity check, could not find index (%s) for PK constraint\n",
+									tblinfo[i].pkIndexOid);
+						exit_nicely(g_conn);
+					}
+
+					consDef = getPKconstraint(&tblinfo[i], &indinfo[k]);
+
+					if ( (actual_atts + tblinfo[i].ncheck) > 0)
 						appendPQExpBuffer(q, ",\n\t");
-					appendPQExpBuffer(q,
-									  "CONSTRAINT %s PRIMARY KEY (%s)",
-									  tblinfo[i].primary_key_name,
-									  tblinfo[i].primary_key);
+
+					appendPQExpBuffer(q, "%s", consDef->data);
+
+					destroyPQExpBuffer(consDef);
 				}
 
+
 				appendPQExpBuffer(q, "\n)");
 
 				if (numParents > 0)
@@ -3690,13 +3705,15 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
 			}
 
 			if (!dataOnly) {
-					ArchiveEntry(fout, tblinfo[i].oid, fmtId(tblinfo[i].relname, false),
+
+				ArchiveEntry(fout, tblinfo[i].oid, fmtId(tblinfo[i].relname, false),
 								reltypename, NULL, q->data, delq->data, "", tblinfo[i].usename,
 								NULL, NULL);
-			}
 
-			if (!dataOnly && !aclsSkip)
-				dumpACL(fout, tblinfo[i]);
+				if (!aclsSkip)
+					dumpACL(fout, tblinfo[i]);
+
+			}
 
 			/* Dump Field Comments */
 
@@ -3719,6 +3736,41 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
 	}
 }
 
+static PQExpBuffer getPKconstraint(TableInfo *tblInfo, IndInfo *indInfo)
+{
+	PQExpBuffer 	pkBuf = createPQExpBuffer();
+	int				k;
+	int				indkey;
+
+   	resetPQExpBuffer(pkBuf);
+
+	appendPQExpBuffer(pkBuf, "Constraint %s Primary Key (",
+						tblInfo->primary_key_name);
+
+
+	for (k = 0; k < INDEX_MAX_KEYS; k++)
+	{
+		char	   *attname;
+
+		indkey = atoi(indInfo->indkey[k]);
+		if (indkey == InvalidAttrNumber)
+			break;
+		indkey--;
+		if (indkey == ObjectIdAttributeNumber - 1)
+			attname = "oid";
+		else
+			attname = tblInfo->attnames[indkey];
+
+		appendPQExpBuffer(pkBuf, "%s%s",
+							(k == 0) ? "" : ", ", 
+							fmtId(attname, force_quotes));
+	}
+
+	appendPQExpBuffer(pkBuf, ")");
+
+	return pkBuf;
+}
+
 /*
  * dumpIndices:
  *	  write out to fout all the user-define indices
@@ -3755,6 +3807,31 @@ dumpIndices(Archive *fout, IndInfo *indinfo, int numIndices,
 			exit(1);
 		}
 
+		/* Handle PK indexes */
+		if (strcmp(indinfo[i].indisprimary, "t") == 0)
+		{
+/*
+ *			***PK: Enable this code when ALTER TABLE supports PK constraints. ***
+ *
+ *			PQExpBuffer	consDef = getPKconstraint(&tblinfo[tableInd], &indinfo[i]);
+ *
+ *			resetPQExpBuffer(attlist);
+ *
+ *			appendPQExpBuffer(attlist, "Alter Table %s Add %s;", 
+ *								fmtId(tblinfo[tableInd].relname, force_quotes),
+ *								consDef->data);
+ *
+ *			ArchiveEntry(fout, indinfo[i].oid, tblinfo[tableInd].primary_key_name, "CONSTRAINT", NULL, 
+ *							attlist->data, "",
+ *							"", tblinfo[tableInd].usename, NULL, NULL);
+ *
+ *			destroyPQExpBuffer(consDef);
+ */
+			/* Don't need to do anything else for this system-generated index */
+			continue;
+		}
+
+
 		if (strcmp(indinfo[i].indproc, "0") == 0)
 			funcname = NULL;
 		else
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 1871ed3e2f641d873480250c38e5c30e386f94db..c734cf2c77f00bdc6066baac25ea83e955bdbd47 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-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_dump.h,v 1.55 2000/11/27 20:51:40 momjian Exp $
+ * $Id: pg_dump.h,v 1.56 2001/01/12 15:41:29 pjw Exp $
  *
  * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
  *
@@ -116,7 +116,7 @@ typedef struct _tableInfo
 	char	  **check_expr;		/* [CONSTRAINT name] CHECK expressions */
 	int			ntrig;			/* # of triggers */
 	TrigInfo	*triggers;		/* Triggers on the table */
-	char	   *primary_key;	/* PRIMARY KEY of the table, if any */
+	char	   *pkIndexOid;		/* Primary Key index OID */
 	char	   *primary_key_name;	/* PRIMARY KEY name, if any */
 } TableInfo;
 
@@ -128,6 +128,7 @@ typedef struct _inhInfo
 
 typedef struct _indInfo
 {
+	char	   *oid;			/* Oid of the pg_index entry */
 	char	   *indoid;			/* oid of the pg_class entry for the index */
 	char	   *indexrelname;	/* name of the secondary index class */
 	char	   *indrelname;		/* name of the indexed heap class */
@@ -139,6 +140,7 @@ typedef struct _indInfo
 										 * attributes */
 	char	   *indclass[INDEX_MAX_KEYS];		/* opclass of the keys */
 	char	   *indisunique;	/* is this index unique? */
+	char	   *indisprimary;	/* is this a PK index? */
 } IndInfo;
 
 typedef struct _aggInfo
@@ -253,6 +255,7 @@ extern void dumpAggs(Archive *fout, AggInfo *agginfo, int numAggregates,
 extern void dumpOprs(Archive *fout, OprInfo *agginfo, int numOperators,
 		 TypeInfo *tinfo, int numTypes);
 extern void dumpTables(Archive *fout, TableInfo *tbinfo, int numTables,
+		   IndInfo *indinfo, int numIndices,
 		   InhInfo *inhinfo, int numInherits,
 		   TypeInfo *tinfo, int numTypes, const char *tablename,
 		   const bool acls, const bool oids,