diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index b6487d342596cd041088c91b0637cf0d8172158b..d8a969b41e0279623081d0869737c869be389845 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -23,6 +23,10 @@
  * Modifications - 31-Jul-2000 - pjw@rhyme.com.au (1.46, 1.47)
  *		Fixed version number initialization in _allocAH (pg_backup_archiver.c)
  *
+ *
+ * Modifications - 30-Oct-2000 - pjw@rhyme.com.au
+ *		Added {Start,End}RestoreBlobs to allow extended TX during BLOB restore.
+ *
  *-------------------------------------------------------------------------
  */
 
@@ -590,6 +594,34 @@ int EndBlob(Archive* AHX, int oid)
  * BLOB Restoration
  **********/
 
+/*
+ * Called by a format handler before any blobs are restored 
+ */
+void StartRestoreBlobs(ArchiveHandle* AH)
+{
+	AH->blobCount = 0;
+}
+
+/*
+ * Called by a format handler after all blobs are restored 
+ */
+void EndRestoreBlobs(ArchiveHandle* AH)
+{
+	if (AH->txActive)
+	{
+		ahlog(AH, 2, "Committing BLOB transactions\n");
+		CommitTransaction(AH);
+	}
+
+	if (AH->blobTxActive)
+	{
+		CommitTransactionXref(AH);
+	}
+
+	ahlog(AH, 1, "Restored %d BLOBs\n", AH->blobCount);
+}
+
+
 /*
  * Called by a format handler to initiate restoration of a blob
  */
@@ -597,6 +629,8 @@ void StartRestoreBlob(ArchiveHandle* AH, int oid)
 {
 	int			loOid;
 
+	AH->blobCount++;
+
 	if (!AH->createdBlobXref)
 	{
 		if (!AH->connection)
@@ -606,7 +640,18 @@ void StartRestoreBlob(ArchiveHandle* AH, int oid)
 		AH->createdBlobXref = 1;
 	}
 
-	StartTransaction(AH);
+	/*
+	 * Start long-running TXs if necessary
+	 */
+	if (!AH->txActive)
+	{
+		ahlog(AH, 2, "Starting BLOB transactions\n");
+		StartTransaction(AH);
+	}
+	if (!AH->blobTxActive)
+	{
+		StartTransactionXref(AH);
+	}
 
 	loOid = lo_creat(AH->connection, INV_READ | INV_WRITE);
 	if (loOid == 0)
@@ -628,7 +673,15 @@ void EndRestoreBlob(ArchiveHandle* AH, int oid)
     lo_close(AH->connection, AH->loFd);
     AH->writingBlob = 0;
 
-	CommitTransaction(AH);
+	/*
+	 * Commit every BLOB_BATCH_SIZE blobs...
+	 */
+	if ( ((AH->blobCount / BLOB_BATCH_SIZE) * BLOB_BATCH_SIZE) == AH->blobCount) 
+	{
+		ahlog(AH, 2, "Committing BLOB transactions\n");
+		CommitTransaction(AH);
+		CommitTransactionXref(AH);
+	}
 }
 
 /***********
diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h
index 41fbb5c9c06a0918aeb480969105629cd0974a94..2c7291e6c6917f678c6711c2ecac34c532546412 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 21 
+#define K_VERS_REV 22 
 
 /* Data block types */
 #define BLK_DATA 1
@@ -76,6 +76,9 @@ typedef z_stream *z_streamp;
 #define K_VERS_1_4 (( (1 * 256 + 4) * 256 + 0) * 256 + 0) /* Date & name in header */
 #define K_VERS_MAX (( (1 * 256 + 4) * 256 + 255) * 256 + 0)
 
+/* No of BLOBs to restore in 1 TX */
+#define BLOB_BATCH_SIZE	100
+
 struct _archiveHandle;
 struct _tocEntry;
 struct _restoreList;
@@ -186,6 +189,8 @@ typedef struct _archiveHandle {
 	char				*pgport;
 	PGconn				*connection;
 	PGconn				*blobConnection;	/* Connection for BLOB xref */
+	int					txActive;			/* Flag set if TX active on connection */
+	int					blobTxActive;		/* Flag set if TX active on blobConnection */
 	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 */
@@ -193,6 +198,7 @@ typedef struct _archiveHandle {
 	int					loFd;				/* BLOB fd */
 	int					writingBlob;		/* Flag */
 	int					createdBlobXref;	/* Flag */
+	int					blobCount;			/* # of blobs restored */
 
 	int					lastID;				/* Last internal ID for a TOC entry */
 	char*				fSpec;				/* Archive File Spec */
@@ -256,8 +262,10 @@ extern int 				ReadInt(ArchiveHandle* AH);
 extern char* 			ReadStr(ArchiveHandle* AH);
 extern int 				WriteStr(ArchiveHandle* AH, char* s);
 
+extern void				StartRestoreBlobs(ArchiveHandle* AH);
 extern void 			StartRestoreBlob(ArchiveHandle* AH, int oid);
 extern void 			EndRestoreBlob(ArchiveHandle* AH, int oid);
+extern void				EndRestoreBlobs(ArchiveHandle* AH);
 
 extern void 			InitArchiveFmt_Custom(ArchiveHandle* AH);
 extern void 			InitArchiveFmt_Files(ArchiveHandle* AH);
diff --git a/src/bin/pg_dump/pg_backup_custom.c b/src/bin/pg_dump/pg_backup_custom.c
index f5b208e233ebc933b11e00a73390c51a1ce858e7..e44f02259c00e572ddbc5da2dd66d83779075e04 100644
--- a/src/bin/pg_dump/pg_backup_custom.c
+++ b/src/bin/pg_dump/pg_backup_custom.c
@@ -585,6 +585,8 @@ static void	_LoadBlobs(ArchiveHandle* AH)
 {
     int		oid;
 
+	StartRestoreBlobs(AH);
+
     oid = ReadInt(AH);
     while(oid != 0)
     {
@@ -593,6 +595,9 @@ static void	_LoadBlobs(ArchiveHandle* AH)
 		EndRestoreBlob(AH, oid);
 		oid = ReadInt(AH);
     }
+
+	EndRestoreBlobs(AH);
+
 }
 
 /*
@@ -608,8 +613,8 @@ static void	_skipBlobs(ArchiveHandle* AH)
     oid = ReadInt(AH);
     while(oid != 0)
     {
-	_skipData(AH);
-	oid = ReadInt(AH);
+		_skipData(AH);
+		oid = ReadInt(AH);
     }
 }
 
diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c
index d606508a36a4c8d80520be8cbbcab0e7effe3fb9..4b8873c3a2360e420ff520128148d2481b84c490 100644
--- a/src/bin/pg_dump/pg_backup_db.c
+++ b/src/bin/pg_dump/pg_backup_db.c
@@ -675,6 +675,17 @@ void StartTransaction(ArchiveHandle* AH)
 	appendPQExpBuffer(qry, "Begin;");
 
 	ExecuteSqlCommand(AH, qry, "can not start database transaction");
+	AH->txActive = true;
+}
+
+void StartTransactionXref(ArchiveHandle* AH)
+{
+	PQExpBuffer		qry = createPQExpBuffer();
+
+	appendPQExpBuffer(qry, "Begin;");
+
+	_executeSqlCommand(AH, AH->blobConnection, qry, "can not start BLOB xref transaction");
+	AH->blobTxActive = true;
 }
 
 void CommitTransaction(ArchiveHandle* AH)
@@ -684,6 +695,15 @@ void CommitTransaction(ArchiveHandle* AH)
     appendPQExpBuffer(qry, "Commit;");
 
     ExecuteSqlCommand(AH, qry, "can not commit database transaction");
+	AH->txActive = false;
 }
 
+void CommitTransactionXref(ArchiveHandle* AH)
+{
+	PQExpBuffer		qry = createPQExpBuffer();
 
+	appendPQExpBuffer(qry, "Commit;");
+
+	_executeSqlCommand(AH, AH->blobConnection, qry, "can not commit BLOB xref transaction");
+	AH->blobTxActive = false;
+}
diff --git a/src/bin/pg_dump/pg_backup_db.h b/src/bin/pg_dump/pg_backup_db.h
index 5d03967f583df5c1524116682c91922d8318fb64..3dfc6664fc934f349342ddf25b0ef28cde541f9e 100644
--- a/src/bin/pg_dump/pg_backup_db.h
+++ b/src/bin/pg_dump/pg_backup_db.h
@@ -12,5 +12,7 @@ extern int ExecuteSqlCommandBuf(ArchiveHandle* AH, void *qry, int bufLen);
 extern void CreateBlobXrefTable(ArchiveHandle* AH);
 extern void InsertBlobXref(ArchiveHandle* AH, int old, int new);
 extern void StartTransaction(ArchiveHandle* AH);
+extern void StartTransactionXref(ArchiveHandle* AH);
 extern void CommitTransaction(ArchiveHandle* AH);
+extern void CommitTransactionXref(ArchiveHandle* AH);
 
diff --git a/src/bin/pg_dump/pg_backup_files.c b/src/bin/pg_dump/pg_backup_files.c
index 1583a497b9c87e4c27f1d040c60e681327f75a91..1624bf14355a791fa02a53c57e13caff09df5c60 100644
--- a/src/bin/pg_dump/pg_backup_files.c
+++ b/src/bin/pg_dump/pg_backup_files.c
@@ -318,6 +318,8 @@ static void	_LoadBlobs(ArchiveHandle* AH, RestoreOptions *ropt)
 	lclContext*		ctx = (lclContext*)AH->formatData;
 	char			fname[K_STD_BUF_SIZE];
 
+	StartRestoreBlobs(AH);
+
 	ctx->blobToc = fopen("blobs.toc", PG_BINARY_R);
 
 	_getBlobTocEntry(AH, &oid, fname);
@@ -331,6 +333,8 @@ static void	_LoadBlobs(ArchiveHandle* AH, RestoreOptions *ropt)
     }
 
 	fclose(ctx->blobToc);
+
+	EndRestoreBlobs(AH);
 }
 
 
diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c
index a137513e78c2e6f15bcb1352df851465bd4a8347..cb4a9e906d22e23952e12e70b44cd3d646216ea8 100644
--- a/src/bin/pg_dump/pg_backup_tar.c
+++ b/src/bin/pg_dump/pg_backup_tar.c
@@ -627,6 +627,8 @@ static void	_LoadBlobs(ArchiveHandle* AH, RestoreOptions *ropt)
 	int				cnt;
 	char			buf[4096];
 
+	StartRestoreBlobs(AH);
+
 	th = tarOpen(AH, NULL, 'r'); /* Open next file */
 	while (th != NULL)
 	{
@@ -652,21 +654,8 @@ static void	_LoadBlobs(ArchiveHandle* AH, RestoreOptions *ropt)
 		th = tarOpen(AH, NULL, 'r');
 	}
 
-	/*
-	 * ctx->blobToc = tarOpen(AH, "blobs.toc", 'r');
-	 *
-	 * _getBlobTocEntry(AH, &oid, fname);
-	 *
-     * while(oid != 0)
-     * {
-	 *		StartRestoreBlob(AH, oid);
-	 *		_PrintFileData(AH, fname, ropt);
-	 *		EndRestoreBlob(AH, oid);
-	 *		_getBlobTocEntry(AH, &oid, fname);
-     * }
-	 *
-	 * tarClose(AH, ctx->blobToc);
-	 */	
+	EndRestoreBlobs(AH);
+
 }
 
 
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 0ae0ee00144182773c2843f96627b660b03c27e2..4b765f528806ad1c216b60ed65ba70888766a79d 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.176 2000/10/24 13:24:30 pjw Exp $
+ *	  $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.177 2000/10/31 14:20:30 pjw Exp $
  *
  * Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
  *
@@ -2872,6 +2872,7 @@ dumpProcLangs(Archive *fout, FuncInfo *finfo, int numFuncs,
 	int			i_lanpltrusted;
 	int			i_lanplcallfoid;
 	int			i_lancompiler;
+	Oid			lanoid;
 	char	   *lanname;
 	char	   *lancompiler;
 	const char *lanplcallfoid;
@@ -2898,7 +2899,13 @@ dumpProcLangs(Archive *fout, FuncInfo *finfo, int numFuncs,
 
 	for (i = 0; i < ntups; i++)
 	{
+		lanoid = atoi(PQgetvalue(res, i, i_oid));
+		if (lanoid <= g_last_builtin_oid)
+			continue;
+
 		lanplcallfoid = PQgetvalue(res, i, i_lanplcallfoid);
+
+
 		for (fidx = 0; fidx < numFuncs; fidx++)
 		{
 			if (!strcmp(finfo[fidx].oid, lanplcallfoid))