diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index 4c99d51bfedd7f23e0321517c7e5335208e7b5b3..675da67d9c80893b37afa27c5594f3a40ef5d0d3 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.38 2001/11/08 04:05:12 tgl Exp $
+ *		$Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.39 2002/01/18 17:13:50 tgl Exp $
  *
  * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
  *
@@ -62,6 +62,11 @@
  *		backup file; prior version was restoring schema in data-only
  *		restores. Added enum to make code easier to understand.
  *
+ * Modifications - 18-Jan-2002 - pjw@rhyme.com.au
+ *	  - Modified _tocEntryRequired to handle '<Init>/Max OID' as a special
+ * 		case (ie. as a DATA item) as per bugs reported by Bruce Momjian
+ *		around 17-Jan-2002.
+ *
  *-------------------------------------------------------------------------
  */
 
@@ -1917,6 +1922,13 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt)
 			res = res & ~REQ_DATA;
 	}
 
+    /* Special case: <Init> type with <Max OID> name; this is part of
+     * a DATA restore even though it has SQL.
+     */
+	if (  ( strcmp(te->desc, "<Init>") == 0 ) && ( strcmp(te->name, "Max OID") == 0) ) {
+		res = REQ_DATA;
+	}
+
 	/* Mask it if we only want schema */
 	if (ropt->schemaOnly)
 		res = res & REQ_SCHEMA;
diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c
index aeea9d02c88b06a56daa3fce474fe58285d89722..ff31b4789e7387d539fb9867c6bd57d607e27fc8 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.29 2001/10/25 05:49:52 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.30 2002/01/18 17:13:51 tgl Exp $
  *
  * NOTES
  *
@@ -17,6 +17,14 @@
  *
  *	  - Avoid forcing table name to lower case in FixupBlobXrefs!
  *
+ *
+ * Modifications - 18-Jan-2002 - pjw@rhyme.com.au
+ *
+ *    - Split ExecuteSqlCommandBuf into 3 routines for (slightly) improved 
+ *		clarity. Modify loop to cater for COPY commands buried in the SQL
+ *		command buffer (prev version assumed COPY command was executed
+ *		in prior call). This was to fix the buf in the 'set max oid' code.
+ *
  *-------------------------------------------------------------------------
  */
 
@@ -43,6 +51,8 @@ static void _check_database_version(ArchiveHandle *AH, bool ignoreVersion);
 static PGconn *_connectDB(ArchiveHandle *AH, const char *newdbname, const char *newUser);
 static int	_executeSqlCommand(ArchiveHandle *AH, PGconn *conn, PQExpBuffer qry, char *desc);
 static void notice_processor(void *arg, const char *message);
+static char* _sendSQLLine( ArchiveHandle *AH, char *qry, char *eos);
+static char* _sendCopyLine( ArchiveHandle *AH, char *qry, char *eos);
 
 
 /*
@@ -534,206 +544,229 @@ _executeSqlCommand(ArchiveHandle *AH, PGconn *conn, PQExpBuffer qry, char *desc)
 	return strlen(qry->data);
 }
 
-/* Convenience function to send one or more queries. Monitors result to handle COPY statements */
-int
-ExecuteSqlCommandBuf(ArchiveHandle *AH, void *qryv, int bufLen)
+/* 
+ * Used by ExecuteSqlCommandBuf to send one buffered line when running a COPY command.
+ */
+static char*
+_sendCopyLine( ArchiveHandle *AH, char *qry, char *eos) 
 {
-	int			loc;
-	int			pos = 0;
-	int			sPos = 0;
-	char	   *qry = (char *) qryv;
-	int			isEnd = 0;
-	char	   *eos = qry + bufLen;
+	int			loc; /* Location of next newline */
+    int			pos = 0; /* Current position */ 
+	int 		sPos = 0; /* Last pos of a slash char */
+    int         isEnd = 0;
 
-	/*
-	 * fprintf(stderr, "\n\n*****\n
-	 * Buffer:\n\n%s\n*******************\n\n", qry);
-	 */
+	/* loop to find unquoted newline ending the line of COPY data */
+    for (;;) {
+		loc = strcspn(&qry[pos], "\n") + pos;
 
-	/* If we're in COPY IN mode, then just break it into lines and send... */
-	if (AH->pgCopyIn)
-	{
-		for (;;)
+		/* If no match, then wait */
+		if (loc >= (eos - qry))		/* None found */
 		{
+			appendBinaryPQExpBuffer(AH->pgCopyBuf, qry, (eos - qry));
+			return eos;
+		}
 
-			/* Find a lf */
-			loc = strcspn(&qry[pos], "\n") + pos;
-			pos = 0;
-
-			/* If no match, then wait */
-			if (loc >= (eos - qry))		/* None found */
-			{
-				appendBinaryPQExpBuffer(AH->pgCopyBuf, qry, (eos - qry));
-				break;
-			};
-
-			/*
-			 * fprintf(stderr, "Found cr at %d, prev char was %c, next was
-			 * %c\n", loc, qry[loc-1], qry[loc+1]);
-			 */
+		/*
+		 * fprintf(stderr, "Found cr at %d, prev char was %c, next was
+		 * %c\n", loc, qry[loc-1], qry[loc+1]);
+		 */
 
-			/* Count the number of preceding slashes */
-			sPos = loc;
-			while (sPos > 0 && qry[sPos - 1] == '\\')
-				sPos--;
+		/* Count the number of preceding slashes */
+		sPos = loc;
+		while (sPos > 0 && qry[sPos - 1] == '\\')
+			sPos--;
 
-			sPos = loc - sPos;
+		sPos = loc - sPos;
 
-			/*
-			 * If an odd number of preceding slashes, then \n was escaped
-			 * so set the next search pos, and restart (if any left).
-			 */
-			if ((sPos & 1) == 1)
+		/*
+		 * If an odd number of preceding slashes, then \n was escaped
+		 * so set the next search pos, and loop (if any left).
+		 */
+		if ((sPos & 1) == 1)
+		{
+			/* fprintf(stderr, "cr was escaped\n"); */
+			pos = loc + 1;
+			if (pos >= (eos - qry))
 			{
-				/* fprintf(stderr, "cr was escaped\n"); */
-				pos = loc + 1;
-				if (pos >= (eos - qry))
-				{
-					appendBinaryPQExpBuffer(AH->pgCopyBuf, qry, (eos - qry));
-					break;
-				}
+				appendBinaryPQExpBuffer(AH->pgCopyBuf, qry, (eos - qry));
+				return eos;
 			}
-			else
-			{
-				/* We got a good cr */
-				qry[loc] = '\0';
-				appendPQExpBuffer(AH->pgCopyBuf, "%s\n", qry);
-				qry += loc + 1;
-				isEnd = (strcmp(AH->pgCopyBuf->data, "\\.\n") == 0);
+		} else {
+			break;
+		}
+	}
 
-				/*---------
-				 * fprintf(stderr, "Sending '%s' via
-				 *		COPY (at end = %d)\n\n", AH->pgCopyBuf->data, isEnd);
-				 *---------
-				 */
+	/* We found an unquoted newline */
+	qry[loc] = '\0';
+	appendPQExpBuffer(AH->pgCopyBuf, "%s\n", qry);
+	isEnd = (strcmp(AH->pgCopyBuf->data, "\\.\n") == 0);
 
-				if (PQputline(AH->connection, AH->pgCopyBuf->data) != 0)
-					die_horribly(AH, modulename, "error returned by PQputline\n");
+	/*---------
+	 * fprintf(stderr, "Sending '%s' via
+	 *		COPY (at end = %d)\n\n", AH->pgCopyBuf->data, isEnd);
+	 *---------
+	 */
 
-				resetPQExpBuffer(AH->pgCopyBuf);
+	if (PQputline(AH->connection, AH->pgCopyBuf->data) != 0)
+		die_horribly(AH, modulename, "error returned by PQputline\n");
 
-				/*
-				 * fprintf(stderr, "Buffer is '%s'\n",
-				 * AH->pgCopyBuf->data);
-				 */
+	resetPQExpBuffer(AH->pgCopyBuf);
 
-				if (isEnd)
-				{
-					if (PQendcopy(AH->connection) != 0)
-						die_horribly(AH, modulename, "error returned by PQendcopy\n");
+	/*
+	 * fprintf(stderr, "Buffer is '%s'\n",
+	 * AH->pgCopyBuf->data);
+	 */
 
-					AH->pgCopyIn = 0;
-					break;
-				}
+	if (isEnd)
+	{
+		if (PQendcopy(AH->connection) != 0)
+			die_horribly(AH, modulename, "error returned by PQendcopy\n");
 
-			}
+		AH->pgCopyIn = 0;
+	}
 
-			/* Make sure we're not past the original buffer end */
-			if (qry >= eos)
-				break;
+	return qry + loc + 1;
+}
 
-		}
-	}
+/* 
+ * Used by ExecuteSqlCommandBuf to send one buffered line of SQL (not data for the copy command).
+ */
+static char*
+_sendSQLLine( ArchiveHandle *AH, char *qry, char *eos) 
+{
+    int			pos = 0; /* Current position */ 
 
-	/* We may have finished Copy In, and have a non-empty buffer */
-	if (!AH->pgCopyIn)
-	{
-		/*
-		 * The following is a mini state machine to assess then of of an
-		 * SQL statement. It really only needs to parse good SQL, or at
-		 * least that's the theory... End-of-statement is assumed to be an
-		 * unquoted, un commented semi-colon.
-		 */
+	/*
+	 * The following is a mini state machine to assess the end of an
+	 * SQL statement. It really only needs to parse good SQL, or at
+	 * least that's the theory... End-of-statement is assumed to be an
+	 * unquoted, un commented semi-colon.
+	 */
 
-		/*
-		 * fprintf(stderr, "Buffer at start is: '%s'\n\n",
-		 * AH->sqlBuf->data);
-		 */
+	/*
+	 * fprintf(stderr, "Buffer at start is: '%s'\n\n",
+	 * AH->sqlBuf->data);
+	 */
 
-		for (pos = 0; pos < (eos - qry); pos++)
-		{
-			appendPQExpBufferChar(AH->sqlBuf, qry[pos]);
-			/* fprintf(stderr, " %c",qry[pos]); */
+	for (pos = 0; pos < (eos - qry); pos++)
+	{
+		appendPQExpBufferChar(AH->sqlBuf, qry[pos]);
+		/* fprintf(stderr, " %c",qry[pos]); */
 
-			switch (AH->sqlparse.state)
-			{
+		switch (AH->sqlparse.state)
+		{
 
-				case SQL_SCAN:	/* Default state == 0, set in _allocAH */
+			case SQL_SCAN:	/* Default state == 0, set in _allocAH */
 
-					if (qry[pos] == ';' && AH->sqlparse.braceDepth == 0)
-					{
-						/* Send It & reset the buffer */
-
-						/*
-						 * fprintf(stderr, "    sending: '%s'\n\n",
-						 * AH->sqlBuf->data);
-						 */
-						ExecuteSqlCommand(AH, AH->sqlBuf, "could not execute query", false);
-						resetPQExpBuffer(AH->sqlBuf);
-						AH->sqlparse.lastChar = '\0';
-					}
-					else
+				if (qry[pos] == ';' && AH->sqlparse.braceDepth == 0)
+				{
+					/* Send It & reset the buffer */
+
+					/*
+					 * fprintf(stderr, "    sending: '%s'\n\n",
+					 * AH->sqlBuf->data);
+					 */
+					ExecuteSqlCommand(AH, AH->sqlBuf, "could not execute query", false);
+					resetPQExpBuffer(AH->sqlBuf);
+					AH->sqlparse.lastChar = '\0';
+
+					/* Remove any following newlines - so that embedded COPY commands don't get a 
+					 * starting newline.
+					 */
+					pos++;
+					for ( ; pos < (eos - qry) && qry[pos] == '\n' ; pos++ ) ;
+
+					/* We've got our line, so exit */
+					return qry + pos;
+				}
+				else
+				{
+					if (qry[pos] == '"' || qry[pos] == '\'')
 					{
-						if (qry[pos] == '"' || qry[pos] == '\'')
-						{
-							/* fprintf(stderr,"[startquote]\n"); */
-							AH->sqlparse.state = SQL_IN_QUOTE;
-							AH->sqlparse.quoteChar = qry[pos];
-							AH->sqlparse.backSlash = 0;
-						}
-						else if (qry[pos] == '-' && AH->sqlparse.lastChar == '-')
-							AH->sqlparse.state = SQL_IN_SQL_COMMENT;
-						else if (qry[pos] == '*' && AH->sqlparse.lastChar == '/')
-							AH->sqlparse.state = SQL_IN_EXT_COMMENT;
-						else if (qry[pos] == '(')
-							AH->sqlparse.braceDepth++;
-						else if (qry[pos] == ')')
-							AH->sqlparse.braceDepth--;
-
-						AH->sqlparse.lastChar = qry[pos];
+						/* fprintf(stderr,"[startquote]\n"); */
+						AH->sqlparse.state = SQL_IN_QUOTE;
+						AH->sqlparse.quoteChar = qry[pos];
+						AH->sqlparse.backSlash = 0;
 					}
+					else if (qry[pos] == '-' && AH->sqlparse.lastChar == '-')
+						AH->sqlparse.state = SQL_IN_SQL_COMMENT;
+					else if (qry[pos] == '*' && AH->sqlparse.lastChar == '/')
+						AH->sqlparse.state = SQL_IN_EXT_COMMENT;
+					else if (qry[pos] == '(')
+						AH->sqlparse.braceDepth++;
+					else if (qry[pos] == ')')
+						AH->sqlparse.braceDepth--;
+
+					AH->sqlparse.lastChar = qry[pos];
+				}
 
-					break;
+				break;
 
-				case SQL_IN_SQL_COMMENT:
+			case SQL_IN_SQL_COMMENT:
 
-					if (qry[pos] == '\n')
-						AH->sqlparse.state = SQL_SCAN;
-					break;
+				if (qry[pos] == '\n')
+					AH->sqlparse.state = SQL_SCAN;
+				break;
 
-				case SQL_IN_EXT_COMMENT:
+			case SQL_IN_EXT_COMMENT:
 
-					if (AH->sqlparse.lastChar == '*' && qry[pos] == '/')
-						AH->sqlparse.state = SQL_SCAN;
-					break;
+				if (AH->sqlparse.lastChar == '*' && qry[pos] == '/')
+					AH->sqlparse.state = SQL_SCAN;
+				break;
 
-				case SQL_IN_QUOTE:
+			case SQL_IN_QUOTE:
 
-					if (!AH->sqlparse.backSlash && AH->sqlparse.quoteChar == qry[pos])
-					{
-						/* fprintf(stderr,"[endquote]\n"); */
-						AH->sqlparse.state = SQL_SCAN;
-					}
-					else
-					{
+				if (!AH->sqlparse.backSlash && AH->sqlparse.quoteChar == qry[pos])
+				{
+					/* fprintf(stderr,"[endquote]\n"); */
+					AH->sqlparse.state = SQL_SCAN;
+				}
+				else
+				{
 
-						if (qry[pos] == '\\')
-						{
-							if (AH->sqlparse.lastChar == '\\')
-								AH->sqlparse.backSlash = !AH->sqlparse.backSlash;
-							else
-								AH->sqlparse.backSlash = 1;
-						}
+					if (qry[pos] == '\\')
+					{
+						if (AH->sqlparse.lastChar == '\\')
+							AH->sqlparse.backSlash = !AH->sqlparse.backSlash;
 						else
-							AH->sqlparse.backSlash = 0;
+							AH->sqlparse.backSlash = 1;
 					}
-					break;
+					else
+						AH->sqlparse.backSlash = 0;
+				}
+				break;
 
-			}
-			AH->sqlparse.lastChar = qry[pos];
-			/* fprintf(stderr, "\n"); */
 		}
+		AH->sqlparse.lastChar = qry[pos];
+		/* fprintf(stderr, "\n"); */
+	}
 
+    /* If we get here, we've processed entire string with no complete SQL stmt */
+    return eos;
+
+}
+
+
+/* Convenience function to send one or more queries. Monitors result to handle COPY statements */
+int
+ExecuteSqlCommandBuf(ArchiveHandle *AH, void *qryv, int bufLen)
+{
+	char	   *qry = (char *) qryv;
+	char	   *eos = qry + bufLen;
+
+	/*
+	 * fprintf(stderr, "\n\n*****\n
+	 * Buffer:\n\n%s\n*******************\n\n", qry);
+	 */
+
+	/* Could switch between command and COPY IN mode at each line */
+	while (qry < eos)
+	{
+		if (AH->pgCopyIn) {
+			qry = _sendCopyLine(AH, qry, eos);
+		} else {
+			qry = _sendSQLLine(AH, qry, eos);
+		}
 	}
 
 	return 1;