diff --git a/doc/src/sgml/ref/vacuum.sgml b/doc/src/sgml/ref/vacuum.sgml
index cbb182466ea44d231b4271f54f2c14da9534307b..0722b8068d2f5997fef44c69f1e2f616b4c81e09 100644
--- a/doc/src/sgml/ref/vacuum.sgml
+++ b/doc/src/sgml/ref/vacuum.sgml
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/vacuum.sgml,v 1.14 2001/05/07 00:43:15 tgl Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/vacuum.sgml,v 1.15 2001/05/25 15:34:49 momjian Exp $
 Postgres documentation
 -->
 
@@ -154,7 +154,8 @@ NOTICE:  Index <replaceable class="PARAMETER">index</replaceable>: Pages 28;
 
   <para>
    With no parameter, <command>VACUUM</command> processes every table in the
-   current database.  With a parameter, <command>VACUUM</command> processes
+   current database. It also detects any extraneous files in the
+   database directory.  With a parameter, <command>VACUUM</command> processes
    only that table.
   </para>
 
diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 34c607eab9f3cd547dc279622c33a1c48348cbc9..95547bbe83d3084730d95b82dab066038a030160 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -6,7 +6,7 @@
  * Copyright (c) 2000, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.38 2001/03/22 03:59:17 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.39 2001/05/25 15:34:49 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -16,7 +16,10 @@
 #include "access/transam.h"
 #include "access/xlog.h"
 #include "storage/proc.h"
+#include "storage/sinval.h"
+#include "storage/sinvaladt.h"
 
+extern SISeg	   *shmInvalBuffer;
 
 /* Number of XIDs and OIDs to prefetch (preallocate) per XLOG write */
 #define VAR_XID_PREFETCH		1024
@@ -143,3 +146,44 @@ CheckMaxObjectId(Oid assigned_oid)
 
 	SpinRelease(OidGenLockId);
 }
+
+/*
+ * GetMinBackendOid -- returns lowest oid stored on startup of
+ * each backend.
+ */
+Oid
+GetMinStartupOid(void)
+{
+	SISeg	   *segP = shmInvalBuffer;
+	ProcState  *stateP = segP->procState;
+	int			index;
+	Oid			min_oid;
+
+	/* prime with current oid, no need for lock */
+	min_oid = ShmemVariableCache->nextOid;
+
+	SpinAcquire(SInvalLock);
+
+	for (index = 0; index < segP->lastBackend; index++)
+	{
+		SHMEM_OFFSET pOffset = stateP[index].procStruct;
+
+		if (pOffset != INVALID_OFFSET)
+		{
+			PROC	   *proc = (PROC *) MAKE_PTR(pOffset);
+			Oid			proc_oid;
+
+			proc_oid = proc->startOid;	/* we don't use spin-locking in
+									 * AbortTransaction() ! */
+			if (proc == MyProc || proc_oid <= BootstrapObjectIdData)
+				continue;
+			if (proc_oid < min_oid)
+				min_oid = proc_oid;
+		}
+	}
+
+	SpinRelease(SInvalLock);
+	return min_oid;
+}
+
+
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 8ec2bd07fdd3ded8fd0604b93e82c6f92c7f82fe..e6bdc3a3f2e2b75cb28b4f214e8eb702794eed95 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.193 2001/05/18 21:24:18 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.194 2001/05/25 15:34:49 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -16,9 +16,12 @@
 
 #include <fcntl.h>
 #include <unistd.h>
+#include <stdlib.h>
+#include <limits.h>
 #include <time.h>
 #include <sys/time.h>
 #include <sys/types.h>
+#include <dirent.h>
 #include <sys/file.h>
 #include <sys/stat.h>
 
@@ -30,6 +33,7 @@
 
 #include "access/genam.h"
 #include "access/heapam.h"
+#include "access/transam.h"
 #include "access/xlog.h"
 #include "catalog/catalog.h"
 #include "catalog/catname.h"
@@ -159,6 +163,7 @@ static int	vac_cmp_vtlinks(const void *left, const void *right);
 static bool enough_space(VacPage vacpage, Size len);
 static void init_rusage(VacRUsage *ru0);
 static char *show_rusage(VacRUsage *ru0);
+static void report_orphans(void);
 
 
 /*
@@ -236,6 +241,10 @@ vacuum(VacuumStmt *vacstmt)
 
 	/* clean up */
 	vacuum_shutdown();
+
+	if (VacRelName == NULL)
+		report_orphans();
+
 }
 
 /*
@@ -2646,3 +2655,74 @@ show_rusage(VacRUsage *ru0)
 
 	return result;
 }
+
+/*
+ * report_orphans
+ *
+ * Report files that are not referenced by any pg_class.relfilenode.
+ * Could be caused by backend crash no cleaning up.
+ */
+static void
+report_orphans(void)
+{
+	DIR		   *db_dir;
+	struct dirent  *db_de;
+	Relation	rel;
+	TupleDesc	tupdesc;
+	HeapScanDesc scan;
+	HeapTuple	tuple;
+	Oid			dir_file_oid;
+	Oid			rel_file_oid;
+	Datum		d;
+	bool		n;
+	bool		match_found;
+	char 		cwd[MAXPGPATH];
+
+	getcwd(cwd,MAXPGPATH);
+	db_dir = opendir(".");
+	rel = heap_openr(RelationRelationName, AccessShareLock);
+	Assert(db_dir);
+
+	/*
+	 * Cycle through directory and check each file against
+	 * pg_class.relfilenode.
+	 * XXX This is O(n^2).  Is it too slow?  bjm
+	 */
+	while ((db_de = readdir(db_dir)) != NULL)
+	{
+		if (strspn(db_de->d_name, "0123456789") ==
+			strlen(db_de->d_name))
+		{
+			dir_file_oid = (Oid) strtoul((db_de->d_name), NULL, 10);
+
+			if (dir_file_oid >= GetMinStartupOid() ||
+				dir_file_oid <= BootstrapObjectIdData)
+				continue;
+
+			tupdesc = RelationGetDescr(rel);
+
+			match_found = false;
+			scan = heap_beginscan(rel, false, SnapshotNow, 0, (ScanKey) NULL);
+			while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
+			{
+				d = heap_getattr(tuple, Anum_pg_class_relfilenode, tupdesc, &n);
+				rel_file_oid = DatumGetObjectId(d);
+				if (dir_file_oid == rel_file_oid)
+				{
+					match_found = true;
+					break;
+				}
+			}
+			heap_endscan(scan);
+			/* make sure there was no oid wrap-around during the scan */
+			if (!match_found && dir_file_oid <= ShmemVariableCache->nextOid)
+				elog(NOTICE,
+				"Unreferenced file found in database directory:\n\t%s/%s",
+					cwd, db_de->d_name);
+			/* Maybe one day we can unlink too.  bjm 2001-05-24 */
+		}
+	}
+
+	heap_close(rel, AccessShareLock);
+	closedir(db_dir);
+}
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index f6b8884dcca76d6a68c9831fb7c0afe3574b0a5d..dc6ee27fa0d1c0c06237dc543a55c783f8be2568 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -28,7 +28,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.212 2001/04/19 19:09:23 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.213 2001/05/25 15:34:50 momjian Exp $
  *
  * NOTES
  *
@@ -58,6 +58,7 @@
 #include <ctype.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <dirent.h>
 #include <sys/time.h>
 #include <sys/socket.h>
 #include <errno.h>
@@ -243,6 +244,7 @@ static void RandomSalt(char *salt);
 static void SignalChildren(int signal);
 static int	CountChildren(void);
 static bool CreateOptsFile(int argc, char *argv[]);
+static void RemovePgSorttemp(void);
 
 static pid_t SSDataBase(int xlop);
 
@@ -595,6 +597,9 @@ PostmasterMain(int argc, char *argv[])
 	if (!CreateDataDirLockFile(DataDir, true))
 		ExitPostmaster(1);
 
+	/* Remove old sort files */
+	RemovePgSorttemp();
+
 	/*
 	 * Establish input sockets.
 	 */
@@ -2450,3 +2455,51 @@ CreateOptsFile(int argc, char *argv[])
 	fclose(fp);
 	return true;
 }
+
+
+/*
+ * Remove old sort files
+ */
+static void
+RemovePgSorttemp(void)
+{
+	char 		db_path[MAXPGPATH];
+	char 		temp_path[MAXPGPATH];
+	char 		rm_path[MAXPGPATH];
+	DIR		   *db_dir;
+	DIR		   *temp_dir;
+	struct dirent  *db_de;
+	struct dirent  *temp_de;
+
+	/*
+	 * Cycle through pg_tempsort for all databases and
+	 * and remove old sort files.
+	 */
+	/* trailing slash forces symlink following */
+	snprintf(db_path, sizeof(db_path), "%s/base/",	DataDir);
+	if ((db_dir = opendir(db_path)) != NULL)
+	{
+		while ((db_de = readdir(db_dir)) != NULL)
+		{
+			snprintf(temp_path, sizeof(temp_path),
+				"%s/%s/%s/",	db_path, db_de->d_name, SORT_TEMP_DIR);
+			if ((temp_dir = opendir(temp_path)) != NULL)
+			{
+				while ((temp_de = readdir(temp_dir)) != NULL)
+				{
+					if (strspn(temp_de->d_name, "0123456789.") ==
+						strlen(temp_de->d_name))
+					{
+						snprintf(rm_path, sizeof(temp_path),
+							"%s/%s/%s/%s",
+							db_path, db_de->d_name,
+							SORT_TEMP_DIR, temp_de->d_name);
+						unlink(rm_path);
+					}
+				}
+				closedir(temp_dir);
+			}
+		}
+		closedir(db_dir);
+	}
+}
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 27e53f41c8b0af422936d5f819be6b7dcafd22f4..8816589787a40ea3cdc2607f4f72dc6c736a322e 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.76 2001/04/03 04:07:02 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.77 2001/05/25 15:34:50 momjian Exp $
  *
  * NOTES:
  *
@@ -742,21 +742,29 @@ PathNameOpenFile(FileName fileName, int fileFlags, int fileMode)
 File
 OpenTemporaryFile(void)
 {
-	char		tempfilename[64];
+	char		tempfilepath[128];
 	File		file;
 
 	/*
 	 * Generate a tempfile name that's unique within the current
 	 * transaction
 	 */
-	snprintf(tempfilename, sizeof(tempfilename),
-			 "pg_sorttemp%d.%ld", MyProcPid, tempFileCounter++);
+	snprintf(tempfilepath, sizeof(tempfilepath),
+			 "%s%c%d.%ld", SORT_TEMP_DIR, SEP_CHAR, MyProcPid,
+			 tempFileCounter++);
 
 	/* Open the file */
-	file = FileNameOpenFile(tempfilename,
+	file = FileNameOpenFile(tempfilepath,
 							O_RDWR | O_CREAT | O_TRUNC | PG_BINARY, 0600);
 	if (file <= 0)
-		elog(ERROR, "Failed to create temporary file %s", tempfilename);
+	{
+		/* mkdir could fail if some one else already created it */
+		mkdir(SORT_TEMP_DIR, S_IRWXU);
+		file = FileNameOpenFile(tempfilepath,
+							O_RDWR | O_CREAT | O_TRUNC | PG_BINARY, 0600);
+		if (file <= 0)
+			elog(ERROR, "Failed to create temporary file %s", tempfilepath);
+	}
 
 	/* Mark it for deletion at close or EOXact */
 	VfdCache[file].fdstate |= FD_TEMPORARY;
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index a12d0aa20f98d185bef71352e09235577a940c11..9e9ef04d2cd515cb5ac31dedb7d921aac795ce38 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.100 2001/03/22 06:16:17 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.101 2001/05/25 15:34:50 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -261,6 +261,7 @@ InitProcess(void)
 	MyProc->databaseId = MyDatabaseId;
 	MyProc->xid = InvalidTransactionId;
 	MyProc->xmin = InvalidTransactionId;
+	MyProc->startOid = ShmemVariableCache->nextOid;
 	MyProc->waitLock = NULL;
 	MyProc->waitHolder = NULL;
 	SHMQueueInit(&(MyProc->procHolders));
diff --git a/src/include/access/transam.h b/src/include/access/transam.h
index b18f26b951ef2b148f7171ff4cc498ea6f1fdc3f..6278665345fb78257e751aaa76ae8336a9279176 100644
--- a/src/include/access/transam.h
+++ b/src/include/access/transam.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: transam.h,v 1.33 2001/05/14 20:30:21 momjian Exp $
+ * $Id: transam.h,v 1.34 2001/05/25 15:34:50 momjian Exp $
  *
  *	 NOTES
  *		Transaction System Version 101 now support proper oid
@@ -133,6 +133,7 @@ extern void GetNewTransactionId(TransactionId *xid);
 extern void ReadNewTransactionId(TransactionId *xid);
 extern void GetNewObjectId(Oid *oid_return);
 extern void CheckMaxObjectId(Oid assigned_oid);
+extern Oid GetMinStartupOid(void);
 
 /* ----------------
  *		global variable extern declarations
diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h
index 46ec1fdb94442adcb37ad0f58fb58360b28cd147..d1867bd6106a3018523b0b4a3678516a5b954ebd 100644
--- a/src/include/storage/fd.h
+++ b/src/include/storage/fd.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: fd.h,v 1.27 2001/02/18 04:39:42 tgl Exp $
+ * $Id: fd.h,v 1.28 2001/05/25 15:34:50 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -39,6 +39,8 @@
  * FileSeek uses the standard UNIX lseek(2) flags.
  */
 
+#define SORT_TEMP_DIR "pg_sorttemp"
+
 typedef char *FileName;
 
 typedef int File;
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index 72e2aafd425222ea600c1661a2763f2a67327ca0..ae1fb9f1c008f5f1dfefbb2c6fee39ceaed1e890 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: proc.h,v 1.41 2001/03/22 04:01:08 momjian Exp $
+ * $Id: proc.h,v 1.42 2001/05/25 15:34:50 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -50,6 +50,9 @@ struct proc
 								 * were starting our xact: vacuum must not
 								 * remove tuples deleted by xid >= xmin ! */
 
+	Oid			startOid;		/* oid at startup, used by vacuum to find
+								 * orphaned files.
+								 */
 	/*
 	 * XLOG location of first XLOG record written by this backend's
 	 * current transaction.  If backend is not in a transaction or hasn't
diff --git a/src/interfaces/python/pgmodule.c b/src/interfaces/python/pgmodule.c
index a1ce3cd33fe666c9f7a38646cd5e65b56bb5927f..9cfcd40e5307c3660ed897a65f43e83f35a4f19c 100644
--- a/src/interfaces/python/pgmodule.c
+++ b/src/interfaces/python/pgmodule.c
@@ -947,11 +947,7 @@ pgsource_print(pgsourceobject * self, FILE *fp, int flags)
 
 /* query type definition */
 staticforward PyTypeObject PgSourceType = {
-#ifndef MS_WIN32
-	PyObject_HEAD_INIT(&PyType_Type)
-#else
 	PyObject_HEAD_INIT(NULL)
-#endif
 
 	0,							/* ob_size */
 	"pgsourceobject",			/* tp_name */
@@ -3141,7 +3137,8 @@ init_pg(void)
 			   *v;
 
 	/* Initialize here because some WIN platforms get confused otherwise */
-	PglargeType.ob_type = PgType.ob_type = PgQueryType.ob_type = &PyType_Type;
+	PglargeType.ob_type = PgType.ob_type = PgQueryType.ob_type =
+		PgSourceType.ob_type = &PyType_Type;
 
 	/* Create the module and add the functions */
 	mod = Py_InitModule4("_pg", pg_methods, pg__doc__, NULL, PYTHON_API_VERSION);