diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 4bf31efd8321e75c7aaf2a8150a99be7ea52b48b..add8112710fbedb87bb82386ae417ea0924d685f 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.1.1.1 1996/07/09 06:21:11 scrappy Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.2 1996/08/24 20:47:54 scrappy Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -1093,6 +1093,8 @@ heap_insert(Relation relation, HeapTuple tup)
 	tup->t_oid = newoid();
 	LastOidProcessed = tup->t_oid;
     }
+    else
+    	CheckMaxObjectId(tup->t_oid);
     
     TransactionIdStore(GetCurrentTransactionId(), &(tup->t_xmin));
     tup->t_cmin = GetCurrentCommandId();
diff --git a/src/backend/access/transam.h b/src/backend/access/transam.h
index 0f5a9724dc0fbf29a9aaf4d62783835ef45e71bc..ca9a47e802bfce0e88fcb089022d596b979bfbab 100644
--- a/src/backend/access/transam.h
+++ b/src/backend/access/transam.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: transam.h,v 1.1.1.1 1996/07/09 06:21:09 scrappy Exp $
+ * $Id: transam.h,v 1.2 1996/08/24 20:47:42 scrappy Exp $
  *
  *   NOTES
  *	Transaction System Version 101 now support proper oid
@@ -46,6 +46,14 @@
 
 typedef unsigned char XidStatus; 		/* (2 bits) */
 
+/* ----------
+ *      note: we reserve the first 16384 object ids for internal use.
+ *      oid's less than this appear in the .bki files.  the choice of
+ *      16384 is completely arbitrary.
+ * ----------
+ */
+#define BootstrapObjectIdData 16384
+
 /* ----------------
  *   	BitIndexOf computes the index of the Nth xid on a given block
  * ----------------
@@ -182,6 +190,7 @@ extern void GetNewTransactionId(TransactionId *xid);
 extern void UpdateLastCommittedXid(TransactionId xid);
 extern void GetNewObjectIdBlock(Oid *oid_return, int oid_block_size);
 extern void GetNewObjectId(Oid *oid_return);
+extern void CheckMaxObjectId(Oid assigned_oid);
 
 /* ----------------
  *	global variable extern declarations
diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index a53cc7d35b16e14af6b656b0f1256d00b5045058..5fc47b7228b60f0689caa88b9dad1c514237363c 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.1.1.1 1996/07/09 06:21:13 scrappy Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.2 1996/08/24 20:48:04 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -28,14 +28,6 @@
 
 #include "catalog/catname.h"
 
-/* ----------
- *      note: we reserve the first 16384 object ids for internal use.
- *      oid's less than this appear in the .bki files.  the choice of
- *      16384 is completely arbitrary.
- * ----------
- */
-#define BootstrapObjectIdData 16384
-
 /* ---------------------
  *	spin lock for oid generation
  * ---------------------
@@ -604,3 +596,62 @@ GetNewObjectId(Oid *oid_return)	/* place to return the new object id */
     next_prefetched_oid++;
     prefetched_oid_count--;
 }
+
+void
+CheckMaxObjectId(Oid assigned_oid)
+{
+Oid	pass_oid;
+
+
+    if (prefetched_oid_count == 0)   /* make sure next/max is set, or reload */
+	GetNewObjectId(&pass_oid);
+
+    /* ----------------
+     *  If we are below prefetched limits, do nothing
+     * ----------------
+     */
+    
+    if (assigned_oid < next_prefetched_oid)
+	return;
+
+    /* ----------------
+     *  If we are here, we are coming from a 'copy from' with oid's
+     *
+     *  If we are in the prefetched oid range, just bump it up
+     *
+     * ----------------
+     */
+    
+    if (assigned_oid <= next_prefetched_oid + prefetched_oid_count - 1)
+    {
+	prefetched_oid_count -= assigned_oid - next_prefetched_oid + 1;
+	next_prefetched_oid = assigned_oid + 1;
+	return;
+    }
+
+    /* ----------------
+     *  We have exceeded the prefetch oid range
+     *
+     *  We should lock the database and kill all other backends
+     *  but we are loading oid's that we can not guarantee are unique
+     *  anyway, so we must rely on the user
+     *
+     *
+     * We now:
+     *    set the variable relation with the new max oid
+     *    force the backend to reload its oid cache
+     *
+     * We use the oid cache so we don't have to update the variable
+     * relation every time
+     *
+     * ----------------
+     */
+
+    pass_oid = assigned_oid;
+    VariableRelationPutNextOid(&pass_oid); /* not modified */
+    prefetched_oid_count = 0;	/* force reload */
+    pass_oid = assigned_oid;
+    GetNewObjectId(&pass_oid);	/* throw away returned oid */
+
+}
+
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index e17100a0fb06ac92611b78c46b7f76e9a6c145aa..109f36f3e524958f3ca23981520ebf8ad2c0a58b 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -6,7 +6,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.3 1996/08/14 05:33:04 scrappy Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.4 1996/08/24 20:48:14 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -22,11 +22,13 @@
 #include "catalog/pg_index.h"
 #include "catalog/index.h"
 
+#include "storage/bufmgr.h"
 #include "access/heapam.h"
 #include "access/htup.h"
 #include "access/itup.h"
 #include "access/relscan.h"
 #include "access/funcindex.h"
+#include "access/transam.h"
 #include "access/tupdesc.h"
 #include "nodes/execnodes.h"
 #include "nodes/plannodes.h"
@@ -50,8 +52,8 @@
 static bool reading_from_input = false;
 
 /* non-export function prototypes */
-static void CopyTo(Relation rel, bool binary, FILE *fp, char *delim);
-static void CopyFrom(Relation rel, bool binary, FILE *fp, char *delim);
+static void CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim);
+static void CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim);
 static Oid GetOutputFunction(Oid type);
 static Oid GetTypeElement(Oid type);
 static Oid GetInputFunction(Oid type);
@@ -59,14 +61,14 @@ static Oid IsTypeByVal(Oid type);
 static void GetIndexRelations(Oid main_relation_oid,
 			      int *n_indices,
 			      Relation **index_rels);
-static char *CopyReadAttribute(int attno, FILE *fp, bool *isnull, char *delim);
+static char *CopyReadAttribute(FILE *fp, bool *isnull, char *delim);
 static void CopyAttributeOut(FILE *fp, char *string, char *delim);
 static int CountTuples(Relation relation);
 
 extern FILE *Pfout, *Pfin;
 
 void
-DoCopy(char *relname, bool binary, bool from, bool pipe, char *filename, 
+DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, char *filename, 
        char *delim)
 {
     FILE *fp;
@@ -86,7 +88,7 @@ DoCopy(char *relname, bool binary, bool from, bool pipe, char *filename,
 	if (fp == NULL) {
 	    elog(WARN, "COPY: file %s could not be open for reading", filename);
 	}
-	CopyFrom(rel, binary, fp, delim);
+	CopyFrom(rel, binary, oids, fp, delim);
     }else {
 	
 	mode_t oumask = umask((mode_t) 0);
@@ -102,7 +104,7 @@ DoCopy(char *relname, bool binary, bool from, bool pipe, char *filename,
 	if (fp == NULL)  {
 	    elog(WARN, "COPY: file %s could not be open for writing", filename);
 	}
-	CopyTo(rel, binary, fp, delim);
+	CopyTo(rel, binary, oids, fp, delim);
     }
     if (!pipe) {
 	fclose(fp);
@@ -113,7 +115,7 @@ DoCopy(char *relname, bool binary, bool from, bool pipe, char *filename,
 }
 
 static void
-CopyTo(Relation rel, bool binary, FILE *fp, char *delim)
+CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
 {
     HeapTuple tuple;
     HeapScanDesc scandesc;
@@ -159,6 +161,11 @@ CopyTo(Relation rel, bool binary, FILE *fp, char *delim)
     for (tuple = heap_getnext(scandesc, 0, NULL);
          tuple != NULL; 
          tuple = heap_getnext(scandesc, 0, NULL)) {
+
+        if (oids && !binary) {
+            	fputs(oidout(tuple->t_oid),fp);
+		fputc(delim[0], fp);
+	}
 	
 	for (i = 0; i < attr_count; i++) {
 	    value = (Datum) 
@@ -197,6 +204,9 @@ CopyTo(Relation rel, bool binary, FILE *fp, char *delim)
 	    
 	    length = tuple->t_len - tuple->t_hoff;
 	    fwrite(&length, sizeof(int32), 1, fp);
+            if (oids)
+		fwrite((char *) &tuple->t_oid, sizeof(int32), 1, fp);
+
 	    fwrite(&null_ct, sizeof(int32), 1, fp);
 	    if (null_ct > 0) {
 		for (i = 0; i < attr_count; i++) {
@@ -222,7 +232,7 @@ CopyTo(Relation rel, bool binary, FILE *fp, char *delim)
 }
 
 static void
-CopyFrom(Relation rel, bool binary, FILE *fp, char *delim)
+CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
 {
     HeapTuple tuple;
     IndexTuple ituple;
@@ -260,7 +270,8 @@ CopyFrom(Relation rel, bool binary, FILE *fp, char *delim)
     int n_indices;
     InsertIndexResult indexRes;
     TupleDesc tupDesc;
-
+    Oid loaded_oid;
+    
     tupDesc = RelationGetTupleDescriptor(rel);
     attr = tupDesc->attrs;
     attr_count = tupDesc->natts;
@@ -374,8 +385,18 @@ CopyFrom(Relation rel, bool binary, FILE *fp, char *delim)
     
     while (!done) {
 	if (!binary) {
+	    if (oids) {
+		string = CopyReadAttribute(fp, &isnull, delim);
+		if (string == NULL)
+		    done = 1;
+		else {
+		    loaded_oid = oidin(string);
+		    if (loaded_oid < BootstrapObjectIdData)
+			elog(WARN, "COPY TEXT: Invalid Oid");
+		}
+	    }
 	    for (i = 0; i < attr_count && !done; i++) {
-		string = CopyReadAttribute(i, fp, &isnull, delim);
+		string = CopyReadAttribute(fp, &isnull, delim);
 		if (isnull) {
 		    values[i] = PointerGetDatum(NULL);
 		    nulls[i] = 'n';
@@ -401,6 +422,11 @@ CopyFrom(Relation rel, bool binary, FILE *fp, char *delim)
 	    if (feof(fp)) {
 		done = 1;
 	    }else {
+		if (oids) {
+		    fread(&loaded_oid, sizeof(int32), 1, fp);
+		    if (loaded_oid < BootstrapObjectIdData)
+			elog(WARN, "COPY BINARY: Invalid Oid");
+		}
 		fread(&null_ct, sizeof(int32), 1, fp);
 		if (null_ct > 0) {
 		    for (i = 0; i < null_ct; i++) {
@@ -476,6 +502,8 @@ CopyFrom(Relation rel, bool binary, FILE *fp, char *delim)
 	    
 	tupDesc = CreateTupleDesc(attr_count, attr);
 	tuple = heap_formtuple(tupDesc, values, nulls);
+	if (oids)
+	    tuple->t_oid = loaded_oid;
 	heap_insert(rel, tuple);
 	    
 	if (has_index) {
@@ -699,7 +727,7 @@ inString(char c, char* s)
  */
 
 static char *
-CopyReadAttribute(int attno, FILE *fp, bool *isnull, char *delim)
+CopyReadAttribute(FILE *fp, bool *isnull, char *delim)
 {
     static char attribute[EXT_ATTLEN];
     char c;
diff --git a/src/backend/commands/copy.h b/src/backend/commands/copy.h
index ccd29555626bd79bba98f8f60e0d70375ff3aab7..30b85058528cf58c815c3e7c47b43db052bc06d6 100644
--- a/src/backend/commands/copy.h
+++ b/src/backend/commands/copy.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: copy.h,v 1.1.1.1 1996/07/09 06:21:19 scrappy Exp $
+ * $Id: copy.h,v 1.2 1996/08/24 20:48:16 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -15,7 +15,7 @@
 
 #include "postgres.h"
 
-void DoCopy(char *relname, bool binary, bool from, bool pipe, char *filename,
+void DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, char *filename,
 	    char *delim);
 
 #endif	/* COPY_H */
diff --git a/src/backend/nodes/parsenodes.h b/src/backend/nodes/parsenodes.h
index 07f86b252ef4c854e15423d25a4e6598337b836d..f2c7c5910951a72b03ebe6460c001a1dd237cc86 100644
--- a/src/backend/nodes/parsenodes.h
+++ b/src/backend/nodes/parsenodes.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parsenodes.h,v 1.3 1996/08/06 16:37:53 scrappy Exp $
+ * $Id: parsenodes.h,v 1.4 1996/08/24 20:48:31 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -114,6 +114,7 @@ typedef struct CopyStmt {
     NodeTag		type;
     bool		binary;		/* is a binary copy? */
     char		*relname;	/* the relation to copy */
+    bool		oids;		/* copy oid's? */
     int			direction;	/* TO or FROM */
     char		*filename;	/* if NULL, use stdin/stdout */
     char                *delimiter;     /* delimiter character, \t by default*/
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index b5c80f971ccf867d2a64fcf80d58779950c6cbe1..96dbc55cb70e02db3fa1d0090125e577cc20bd01 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.7 1996/08/15 07:42:29 scrappy Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.8 1996/08/24 20:48:44 scrappy Exp $
  *
  * HISTORY
  *    AUTHOR		DATE		MAJOR EVENT
@@ -122,14 +122,14 @@ static Node *makeA_Expr(int op, char *opname, Node *lexpr, Node *rexpr);
 
 %type <list>	queryblock, relation_name_list, OptTableElementList,
 	tableElementList, OptInherit, definition,
-	opt_with, def_args, def_name_list, func_argtypes, oper_argtypes,
+	opt_with_func, def_args, def_name_list, func_argtypes, oper_argtypes,
 	OptStmtList, OptStmtBlock, opt_column_list, columnList,
 	exprList, sort_clause, sortby_list, index_params, 
 	name_list, from_clause, from_list, opt_array_bounds, nest_array_bounds,
 	expr_list, attrs, res_target_list, res_target_list2, def_list,
 	opt_indirection, group_clause, groupby_list, explain_options
 
-%type <boolean>	opt_inh_star, opt_binary, opt_instead
+%type <boolean>	opt_inh_star, opt_binary, opt_instead, opt_with_copy
 
 %type <ival>	copy_dirn, archive_type, OptArchiveType, OptArchiveLocation, 
 	def_type, opt_direction, remove_type, opt_column, event
@@ -176,7 +176,7 @@ static Node *makeA_Expr(int op, char *opname, Node *lexpr, Node *rexpr);
 	HAVING, HEAVY, IN, INDEX, INHERITS, INSERT, INSTEAD, INTO, IS,
 	ISNULL, LANGUAGE, LIGHT, LISTEN, LOAD, MERGE, MOVE, NEW, 
 	NONE, NOT, NOTHING, NOTIFY, NOTNULL, 
-        ON, OPERATOR, OPTION, OR, ORDER, 
+        OIDS, ON, OPERATOR, OPTION, OR, ORDER, 
         PNULL, PRIVILEGES, PUBLIC, PURGE, P_TYPE, 
         RENAME, REPLACE, RETRIEVE, RETURNS, REVOKE, ROLLBACK, RULE, 
         SELECT, SET, SETOF, STDIN, STDOUT, STORE, 
@@ -306,14 +306,15 @@ ClosePortalStmt:  CLOSE opt_id
  *
  *****************************************************************************/
 
-CopyStmt:  COPY opt_binary relation_name copy_dirn copy_file_name copy_delimiter
+CopyStmt:  COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter
 		{
 		    CopyStmt *n = makeNode(CopyStmt);
 		    n->binary = $2;
 		    n->relname = $3;
-		    n->direction = $4;
-		    n->filename = $5;
-		    n->delimiter = $6;
+		    n->oids = $4;
+		    n->direction = $5;
+		    n->filename = $6;
+		    n->delimiter = $7;
 		    $$ = (Node *)n;
 		}
 	;
@@ -338,6 +339,10 @@ opt_binary: BINARY				{ $$ = TRUE; }
 	|  /*EMPTY*/				{ $$ = FALSE; }
 	;
 
+opt_with_copy:  WITH OIDS			{ $$ = TRUE; }
+	|  /* EMPTY */				{ $$ = FALSE; }
+	;
+
 /*
  * the default copy delimiter is tab but the user can configure it
  */
@@ -725,7 +730,7 @@ RecipeStmt:  EXECUTE RECIPE recipe_name
  *****************************************************************************/
 
 ProcedureStmt:  CREATE FUNCTION def_name def_args 
-		   RETURNS def_arg opt_with AS Sconst LANGUAGE Sconst
+		   RETURNS def_arg opt_with_func AS Sconst LANGUAGE Sconst
                 {
 		    ProcedureStmt *n = makeNode(ProcedureStmt);
 		    n->funcname = $3;
@@ -737,7 +742,7 @@ ProcedureStmt:  CREATE FUNCTION def_name def_args
 		    $$ = (Node *)n;
 		};
 
-opt_with:  WITH definition			{ $$ = $2; }
+opt_with_func:  WITH definition			{ $$ = $2; }
 	|  /* EMPTY */				{ $$ = NIL; }
 	;
 
diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c
index 80a1832575344523b4b1e243a0f348ac706ba093..31c035d42a58ea45a2b97521a61f6f7aa03ef878 100644
--- a/src/backend/parser/keywords.c
+++ b/src/backend/parser/keywords.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.2 1996/08/06 16:43:08 scrappy Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.3 1996/08/24 20:48:46 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -103,6 +103,7 @@ static ScanKeyword ScanKeywords[] = {
 	{ "notify",             NOTIFY          },
 	{ "notnull",            NOTNULL         },
 	{ "null",		PNULL		},
+	{ "oids",		OIDS		},
 	{ "on",			ON		},
 	{ "operator",		OPERATOR	},
         { "option",             OPTION          },
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index e12d18b91eea499162348921ddd6214d7c7da98b..a7df82c0ff4ffdeae64a1d45dbae5848a02c0d21 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.1.1.1 1996/07/09 06:22:00 scrappy Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.2 1996/08/24 20:49:03 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -199,6 +199,7 @@ ProcessUtility(Node *parsetree,
 	    char *filename;
 	    char *delim;
 	    bool	isBinary;
+	    bool	isOids;
 	    bool	isFrom;
 	    bool        pipe = false;
 
@@ -207,6 +208,7 @@ ProcessUtility(Node *parsetree,
 	    
 	    relname = stmt->relname;
 	    isBinary = stmt->binary;
+	    isOids = stmt->oids;
 	    
 	    isFrom = (bool)(stmt->direction == FROM);
 	    filename = stmt->filename;
@@ -234,7 +236,7 @@ ProcessUtility(Node *parsetree,
 	    
 	    if (pipe && IsUnderPostmaster) dest = CopyEnd;
 	    
-	    DoCopy(relname, isBinary, isFrom, pipe, filename, delim);
+	    DoCopy(relname, isBinary, isOids, isFrom, pipe, filename, delim);
 	}
 	break;
       
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
index bcc84f21f78c18604b6dca05b430ab1e9004b63d..1e2ac00e61ff88acd893e1fe71f3ea00fdb19aa4 100644
--- a/src/bin/pg_dump/common.c
+++ b/src/bin/pg_dump/common.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.3 1996/07/22 08:36:59 scrappy Exp $
+ *    $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.4 1996/08/24 20:49:17 scrappy Exp $
  *
  * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
  *
@@ -210,7 +210,6 @@ dumpSchema(FILE *fout, int *numTablesPtr, char *tablename)
     int numFuncs;
     int numTables;
     int numInherits;
-    int numIndices;
     int numAggregates;
     int numOperators;
     TypeInfo *tinfo;
@@ -218,7 +217,6 @@ dumpSchema(FILE *fout, int *numTablesPtr, char *tablename)
     AggInfo *agginfo;
     TableInfo *tblinfo;
     InhInfo *inhinfo;
-    IndInfo *indinfo;
     OprInfo *oprinfo;
 
 if (g_verbose) fprintf(stderr,"%s reading user-defined types %s\n",
@@ -253,10 +251,6 @@ if (g_verbose) fprintf(stderr, "%s flagging inherited attributes in subtables %s
 		       g_comment_start, g_comment_end);
     flagInhAttrs(tblinfo, numTables, inhinfo, numInherits);
 
-if (g_verbose) fprintf(stderr,"%s reading indices information %s\n",
-		       g_comment_start, g_comment_end);
-    indinfo = getIndices(&numIndices);
-
 if (!tablename && fout) {
   if (g_verbose) fprintf(stderr,"%s dumping out user-defined types %s\n",
   		       g_comment_start, g_comment_end);
@@ -288,16 +282,35 @@ if (!tablename && fout) {
       dumpOprs(fout, oprinfo, numOperators, tinfo, numTypes);
 }
 
-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);
-}
     *numTablesPtr = numTables;
     return tblinfo;
 }
 
 
+/*
+ * dumpSchemaIdx:
+ *    dump indexes at the end for performance
+ *
+ */
+
+extern void
+dumpSchemaIdx(FILE *fout, int *numTablesPtr, 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);
+    }
+}
+
 /* flagInhAttrs -
  *   for each table in tblinfo, flag its inherited attributes
  * so when we dump the table out, we don't dump out the inherited attributes
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 98e2fa3fd8a9e21f245aed10085d7535ff553042..c6fd237012cf085eebd374b65166eb6af2c0fb94 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -20,7 +20,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.6 1996/08/14 05:33:11 scrappy Exp $
+ *    $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.7 1996/08/24 20:49:22 scrappy Exp $
  *
  * Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
  *
@@ -80,14 +80,15 @@ usage(char* progname)
     fprintf(stderr, "%s - version 1.13.dhb.2\n\n",progname);
     fprintf(stderr, "usage:  %s [options] [dbname]\n",progname);
     fprintf(stderr, "\t -f filename \t\t script output filename\n");
-    fprintf(stderr, "\t -d[a]       \t\t dump data as proper insert strings\n");
-    fprintf(stderr, "\t             \t\t (if 'a' then attribute names also)\n");
     fprintf(stderr, "\t -H hostname \t\t server host name\n");
     fprintf(stderr, "\t -p port     \t\t server port number\n");
     fprintf(stderr, "\t -v          \t\t verbose\n");
+    fprintf(stderr, "\t -d[a]       \t\t dump data as proper insert strings\n");
+    fprintf(stderr, "\t             \t\t (if 'a' then attribute names also)\n");
     fprintf(stderr, "\t -S          \t\t dump out only the schema, no data\n");
     fprintf(stderr, "\t -a          \t\t dump out only the data, no schema\n");
     fprintf(stderr, "\t -t table    \t\t dump for this table only\n");
+    fprintf(stderr, "\t -o          \t\t dump object id's (oids)\n");
     fprintf(stderr, "\n if dbname is not supplied, then the DATABASE environment name is used\n");
     fprintf(stderr, "\n");
 
@@ -117,7 +118,7 @@ main(int argc, char** argv)
     char *pghost = NULL;
     char *pgport = NULL;
     char *tablename;
-
+    int oids;
     TableInfo *tblinfo;
     int numTables;
 
@@ -125,7 +126,8 @@ main(int argc, char** argv)
     filename = NULL;
     tablename = NULL;
     g_verbose = 0;
-
+    oids = 0;
+    
     strcpy(g_comment_start,"-- ");
     g_comment_end[0] = '\0';
     strcpy(g_opaque_type, "opaque");
@@ -134,7 +136,7 @@ main(int argc, char** argv)
 
     progname = *argv;
 
-    while ((c = getopt(argc, argv,"f:H:p:t:vSDd:a")) != EOF) {
+    while ((c = getopt(argc, argv,"f:H:p:t:vSDd:ao")) != EOF) {
 	switch(c) {
 	case 'f': /* output file name */
 	    filename = optarg;
@@ -161,6 +163,9 @@ main(int argc, char** argv)
 	case 'a': /* Dump data only */
 	    dataOnly = 1;
 	    break;
+	case 'o': /* Dump oids */
+	    oids = 1;
+	    break;
 	default:
 	    usage(progname);
 	    break;
@@ -196,27 +201,27 @@ main(int argc, char** argv)
 
     g_last_builtin_oid = findLastBuiltinOid();
 
+    if (oids)
+        setMaxOid(g_fout);
     if (!dataOnly) {
-
-if (g_verbose) 
-    fprintf(stderr, "%s last builtin oid is %d %s\n",
-	    g_comment_start,  g_last_builtin_oid, g_comment_end);
-
-    tblinfo = dumpSchema(g_fout, &numTables, tablename);
-    
+	if (g_verbose) 
+	    fprintf(stderr, "%s last builtin oid is %d %s\n",
+		    g_comment_start,  g_last_builtin_oid, g_comment_end);
+	tblinfo = dumpSchema(g_fout, &numTables, tablename);
     }
-    else {
+    else
       tblinfo = dumpSchema(NULL, &numTables, tablename);
-    }
     
     if (!schemaOnly) {
-
-if (g_verbose) fprintf(stderr,"%s dumping out the contents of each table %s\n",
+	if (g_verbose)
+	    fprintf(stderr,"%s dumping out the contents of each table %s\n",
 		       g_comment_start, g_comment_end);
-
-      dumpClasses(tblinfo, numTables, g_fout, tablename); 
+      dumpClasses(tblinfo, numTables, g_fout, tablename, oids);
     }     
 
+    if (!dataOnly) /* dump indexes at the end for performance */
+	dumpSchemaIdx(g_fout, &numTables, tablename, tblinfo, numTables);
+    
     fflush(g_fout);
     fclose(g_fout);
 
@@ -771,11 +776,11 @@ getTableAttrs(TableInfo* tblinfo, int numTables)
 	/* we must read the attribute names in attribute number order! */
 	/* because we will use the attnum to index into the attnames array 
 	   later */
-if (g_verbose) 
-    fprintf(stderr,"%s finding the attrs and types for table: %s %s\n",
-	    g_comment_start,
-	    tblinfo[i].relname,
-	    g_comment_end);
+	if (g_verbose) 
+	    fprintf(stderr,"%s finding the attrs and types for table: %s %s\n",
+		g_comment_start,
+		tblinfo[i].relname,
+		g_comment_end);
 
 	sprintf(q,"SELECT a.attnum, a.attname, t.typname, a.attlen from pg_attribute a, pg_type t where a.attrelid = '%s'::oid and a.atttypid = t.oid and a.attnum > 0 order by attnum",tblinfo[i].oid);
 	res = PQexec(g_conn, q);
@@ -1356,7 +1361,7 @@ dumpIndices(FILE* fout, IndInfo* indinfo, int numIndices,
  *    dump the contents of all the classes.
  */
 void
-dumpClasses(TableInfo *tblinfo, int numTables, FILE *fout, char *onlytable)
+dumpClasses(TableInfo *tblinfo, int numTables, FILE *fout, char *onlytable, int oids)
 {
     char query[255];
 #define COPYBUFSIZ	8192
@@ -1371,7 +1376,7 @@ dumpClasses(TableInfo *tblinfo, int numTables, FILE *fout, char *onlytable)
     int field;
     int tuple;
     int copydone;
-
+    
     for(i = 0; i < numTables; i++) {
 	char *classname = tblinfo[i].relname;
 
@@ -1382,8 +1387,14 @@ dumpClasses(TableInfo *tblinfo, int numTables, FILE *fout, char *onlytable)
 	        continue;
 
             if(!dumpData) {
-	        fprintf(fout, "COPY %s from stdin;\n", classname);
-	        sprintf(query, "COPY %s to stdout;\n", classname);
+		if (oids) {
+		    fprintf(fout, "COPY %s WITH OIDS FROM stdin;\n", classname);
+		    sprintf(query, "COPY %s WITH OIDS TO stdout;\n", classname);
+		}
+		else {
+		    fprintf(fout, "COPY %s FROM stdin;\n", classname);
+		    sprintf(query, "COPY %s TO stdout;\n", classname);
+		}
 	        res = PQexec(g_conn, query);
 	        if (!res || 
 	            PQresultStatus(res) != PGRES_COPY_OUT) {
@@ -1538,7 +1549,53 @@ dumpTuples(PGresult *res, FILE *fout, int* attrmap)
     }
 }
 
+/*
+ * setMaxOid -
+ * find the maximum oid and generate a COPY statement to set it
+*/
 
+void
+setMaxOid(FILE *fout)
+{
+    char query[255];
+    PGresult *res;
+    Oid max_oid;
+    
+    res = PQexec(g_conn, "CREATE TABLE pgdump_oid (dummy int4)");
+    if (!res || 
+        PQresultStatus(res) != PGRES_COMMAND_OK) {
+        fprintf(stderr,"Can not create pgdump_oid table\n");
+        exit_nicely(g_conn);
+    }
+    PQclear(res);
+    res = PQexec(g_conn, "INSERT INTO pgdump_oid VALUES (0)");
+    if (!res || 
+        PQresultStatus(res) != PGRES_COMMAND_OK) {
+        fprintf(stderr,"Can not insert into pgdump_oid table\n");
+        exit_nicely(g_conn);
+    }
+    max_oid = atol(PQoidStatus(res));
+    if (max_oid == 0) {
+        fprintf(stderr,"Invalid max id in setMaxOid\n");
+        exit_nicely(g_conn);
+    }
+    PQclear(res);
+    res = PQexec(g_conn, "DROP TABLE pgdump_oid;");
+    if (!res || 
+        PQresultStatus(res) != PGRES_COMMAND_OK) {
+        fprintf(stderr,"Can not drop pgdump_oid table\n");
+        exit_nicely(g_conn);
+    }
+    PQclear(res);
+    if (g_verbose) 
+        fprintf(stderr, "%s maximum system oid is %d %s\n",
+    	    g_comment_start,  max_oid, g_comment_end);
+    fprintf(fout, "CREATE TABLE pgdump_oid (dummy int4);\n");
+    fprintf(fout, "COPY pgdump_oid WITH OIDS FROM stdin;\n");
+    fprintf(fout, "%-ld\t0\n", max_oid);
+    fprintf(fout, "\\.\n");
+    fprintf(fout, "DROP TABLE pgdump_oid;\n");
+}    	
 
 /*
  * findLastBuiltInOid -
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 3d0287fa589fed71f8718faa69b8178a88a40143..7e8a830457d327bc58ac894d37f707d0d9167d8d 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_dump.h,v 1.3 1996/07/22 08:37:00 scrappy Exp $
+ * $Id: pg_dump.h,v 1.4 1996/08/24 20:49:25 scrappy Exp $
  *
  * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
  *
@@ -142,6 +142,8 @@ extern char g_opaque_type[10]; /* name for the opaque type */
 */
 
 extern TableInfo* dumpSchema(FILE* fout, int *numTablesPtr, char *tablename);
+extern void dumpSchemaIdx(FILE* fout, int *numTablesPtr, char *tablename,
+				TableInfo* tblinfo, int numTables);
 
 extern char* findTypeByOid(TypeInfo* tinfo, int numTypes, char* oid);
 extern char* findOprByOid(OprInfo *oprinfo, int numOprs, char *oid);
diff --git a/src/bin/psql/psqlHelp.h b/src/bin/psql/psqlHelp.h
index 2fbe50b02c71eff3d2fe9bc73b8fd291393f4680..eee4cf30c5d8c3dea92d7c0db359f05fb7a98e4f 100644
--- a/src/bin/psql/psqlHelp.h
+++ b/src/bin/psql/psqlHelp.h
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: psqlHelp.h,v 1.2 1996/07/28 07:08:14 scrappy Exp $
+ * $Id: psqlHelp.h,v 1.3 1996/08/24 20:49:41 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -49,7 +49,7 @@ static struct _helpStruct QL_HELP[] = {
       "commit [work]"},
   { "copy",
       "copy data to and from a table",
-      "copy [binary] [nonulls] <relname>\n\t{to|from} {<filename>|stdin|stdout} [using delimiters <delim>];"},
+      "copy [binary] <relname> [with oids]\n\t{to|from} {<filename>|stdin|stdout} [using delimiters <delim>];"},
   { "create",   
       "Please more be specific:",
       "\tcreate aggregate\n\tcreate database\n\tcreate function\n\tcreate index\n\tcreate operator\n\tcreate rule\n\tcreate table\n\tcreate type\n\tcreate view"},
@@ -64,7 +64,7 @@ static struct _helpStruct QL_HELP[] = {
       "create function <function_name> ([<type1>,...<typeN>]) returns <return_type>\n\tas '<object_filename>'|'<sql-queries>'\n\tlanguage 'c'|'sql'|'internal';"},
   { "create index",
       "construct an index",
-      "create index <indexname> on <relname> using <access_method> (<attr1>|<funcname>(<attr1>,...) <type_class1>);"},
+      "create index <indexname> on <relname> [using <access_method>] (<attr1>|<funcname>(<attr1>,...) [<type_class1>]);"},
   { "create operator",
       "create a user-defined operator",
       "create operator <operator_name> (\n\t[leftarg = <type1>][,rightarg = <type2>]\n\t,procedure = <func_name>,\n\t[,commutator = <com_op>][,negator = <neg_op>]\n\t[,restrict = <res_proc>][,hashes]\n\t[,join = <join_proc>][,sort = <sort_op1>...<sort_opN>]);"},