diff -cpr head/src/backend/access/transam/xlogutils.c pgstat_drop_relation/src/backend/access/transam/xlogutils.c
*** head/src/backend/access/transam/xlogutils.c	Thu May  3 08:18:03 2007
--- pgstat_drop_relation/src/backend/access/transam/xlogutils.c	Tue Jun 26 19:55:48 2007
*************** XLogOpenRelation(RelFileNode rnode)
*** 458,464 ****
  		 * during a crash.	Better to write the data until we are actually
  		 * told to delete the file.)
  		 */
! 		smgrcreate(res->reldata.rd_smgr, res->reldata.rd_istemp, true);
  	}
  
  	res->moreRecently = &(_xlrelarr[0]);
--- 458,464 ----
  		 * during a crash.	Better to write the data until we are actually
  		 * told to delete the file.)
  		 */
! 		smgrcreate(InvalidOid, res->reldata.rd_smgr, res->reldata.rd_istemp, true);
  	}
  
  	res->moreRecently = &(_xlrelarr[0]);
diff -cpr head/src/backend/catalog/heap.c pgstat_drop_relation/src/backend/catalog/heap.c
*** head/src/backend/catalog/heap.c	Mon Jun  4 07:16:02 2007
--- pgstat_drop_relation/src/backend/catalog/heap.c	Tue Jun 26 19:55:48 2007
*************** heap_create(const char *relname,
*** 286,292 ****
  	{
  		Assert(rel->rd_smgr == NULL);
  		RelationOpenSmgr(rel);
! 		smgrcreate(rel->rd_smgr, rel->rd_istemp, false);
  	}
  
  	return rel;
--- 286,292 ----
  	{
  		Assert(rel->rd_smgr == NULL);
  		RelationOpenSmgr(rel);
! 		smgrcreate(RelationGetRelid(rel), rel->rd_smgr, rel->rd_istemp, false);
  	}
  
  	return rel;
*************** heap_drop_with_catalog(Oid relid)
*** 1357,1363 ****
  		rel->rd_rel->relkind != RELKIND_COMPOSITE_TYPE)
  	{
  		RelationOpenSmgr(rel);
! 		smgrscheduleunlink(rel->rd_smgr, rel->rd_istemp);
  	}
  
  	/*
--- 1357,1363 ----
  		rel->rd_rel->relkind != RELKIND_COMPOSITE_TYPE)
  	{
  		RelationOpenSmgr(rel);
! 		smgrscheduleunlink(RelationGetRelid(rel),rel->rd_smgr, rel->rd_istemp);
  	}
  
  	/*
diff -cpr head/src/backend/catalog/index.c pgstat_drop_relation/src/backend/catalog/index.c
*** head/src/backend/catalog/index.c	Thu May 31 05:11:55 2007
--- pgstat_drop_relation/src/backend/catalog/index.c	Tue Jun 26 19:55:48 2007
*************** index_drop(Oid indexId)
*** 840,846 ****
  	 * Schedule physical removal of the file
  	 */
  	RelationOpenSmgr(userIndexRelation);
! 	smgrscheduleunlink(userIndexRelation->rd_smgr,
  					   userIndexRelation->rd_istemp);
  
  	/*
--- 840,847 ----
  	 * Schedule physical removal of the file
  	 */
  	RelationOpenSmgr(userIndexRelation);
! 	smgrscheduleunlink(RelationGetRelid(userIndexRelation),
! 					   userIndexRelation->rd_smgr,
  					   userIndexRelation->rd_istemp);
  
  	/*
*************** setNewRelfilenode(Relation relation, Tra
*** 1237,1248 ****
  	newrnode.relNode = newrelfilenode;
  
  	srel = smgropen(newrnode);
! 	smgrcreate(srel, relation->rd_istemp, false);
  	smgrclose(srel);
  
  	/* schedule unlinking old relfilenode */
  	RelationOpenSmgr(relation);
! 	smgrscheduleunlink(relation->rd_smgr, relation->rd_istemp);
  
  	/* update the pg_class row */
  	rd_rel->relfilenode = newrelfilenode;
--- 1238,1250 ----
  	newrnode.relNode = newrelfilenode;
  
  	srel = smgropen(newrnode);
! 	smgrcreate(RelationGetRelid(relation), srel, relation->rd_istemp, false);
  	smgrclose(srel);
  
  	/* schedule unlinking old relfilenode */
  	RelationOpenSmgr(relation);
! 	smgrscheduleunlink(RelationGetRelid(relation),
! 		relation->rd_smgr, relation->rd_istemp);
  
  	/* update the pg_class row */
  	rd_rel->relfilenode = newrelfilenode;
diff -cpr head/src/backend/commands/tablecmds.c pgstat_drop_relation/src/backend/commands/tablecmds.c
*** head/src/backend/commands/tablecmds.c	Sun Jun 24 07:12:50 2007
--- pgstat_drop_relation/src/backend/commands/tablecmds.c	Tue Jun 26 19:55:48 2007
*************** ATExecSetTableSpace(Oid tableOid, Oid ne
*** 5828,5841 ****
  	newrnode.spcNode = newTableSpace;
  
  	dstrel = smgropen(newrnode);
! 	smgrcreate(dstrel, rel->rd_istemp, false);
  
  	/* copy relation data to the new physical file */
  	copy_relation_data(rel, dstrel);
  
  	/* schedule unlinking old physical file */
  	RelationOpenSmgr(rel);
! 	smgrscheduleunlink(rel->rd_smgr, rel->rd_istemp);
  
  	/*
  	 * Now drop smgr references.  The source was already dropped by
--- 5828,5841 ----
  	newrnode.spcNode = newTableSpace;
  
  	dstrel = smgropen(newrnode);
! 	smgrcreate(tableOid, dstrel, rel->rd_istemp, false);
  
  	/* copy relation data to the new physical file */
  	copy_relation_data(rel, dstrel);
  
  	/* schedule unlinking old physical file */
  	RelationOpenSmgr(rel);
! 	smgrscheduleunlink(RelationGetRelid(rel), rel->rd_smgr, rel->rd_istemp);
  
  	/*
  	 * Now drop smgr references.  The source was already dropped by
Only in pgstat_drop_relation/src/backend/commands: tablecmds.c.orig
diff -cpr head/src/backend/rewrite/rewriteDefine.c pgstat_drop_relation/src/backend/rewrite/rewriteDefine.c
*** head/src/backend/rewrite/rewriteDefine.c	Sun Jun 24 07:12:51 2007
--- pgstat_drop_relation/src/backend/rewrite/rewriteDefine.c	Tue Jun 26 19:55:48 2007
*************** DefineQueryRewrite(char *rulename,
*** 477,483 ****
  	if (RelisBecomingView)
  	{
  		RelationOpenSmgr(event_relation);
! 		smgrscheduleunlink(event_relation->rd_smgr, event_relation->rd_istemp);
  	}
  
  	/* Close rel, but keep lock till commit... */
--- 477,484 ----
  	if (RelisBecomingView)
  	{
  		RelationOpenSmgr(event_relation);
! 		smgrscheduleunlink(RelationGetRelid(event_relation),
! 			event_relation->rd_smgr, event_relation->rd_istemp);
  	}
  
  	/* Close rel, but keep lock till commit... */
diff -cpr head/src/backend/storage/smgr/smgr.c pgstat_drop_relation/src/backend/storage/smgr/smgr.c
*** head/src/backend/storage/smgr/smgr.c	Sat Jan  6 07:19:39 2007
--- pgstat_drop_relation/src/backend/storage/smgr/smgr.c	Tue Jun 26 19:55:48 2007
*************** static HTAB *SMgrRelationHash = NULL;
*** 99,105 ****
  
  typedef struct PendingRelDelete
  {
! 	RelFileNode relnode;		/* relation that may need to be deleted */
  	int			which;			/* which storage manager? */
  	bool		isTemp;			/* is it a temporary relation? */
  	bool		atCommit;		/* T=delete at commit; F=delete at abort */
--- 99,106 ----
  
  typedef struct PendingRelDelete
  {
! 	Oid			relid;			/* relation id that may need to be deleted */
! 	RelFileNode relnode;		/* relfilenode that may need to be deleted */
  	int			which;			/* which storage manager? */
  	bool		isTemp;			/* is it a temporary relation? */
  	bool		atCommit;		/* T=delete at commit; F=delete at abort */
*************** typedef struct xl_smgr_truncate
*** 135,141 ****
  
  /* local function prototypes */
  static void smgrshutdown(int code, Datum arg);
! static void smgr_internal_unlink(RelFileNode rnode, int which,
  					 bool isTemp, bool isRedo);
  
  
--- 136,142 ----
  
  /* local function prototypes */
  static void smgrshutdown(int code, Datum arg);
! static void smgr_internal_unlink(Oid relid, RelFileNode rnode, int which,
  					 bool isTemp, bool isRedo);
  
  
*************** smgrclosenode(RelFileNode rnode)
*** 321,327 ****
   *		tell whether to drop the file.
   */
  void
! smgrcreate(SMgrRelation reln, bool isTemp, bool isRedo)
  {
  	XLogRecPtr	lsn;
  	XLogRecData rdata;
--- 322,328 ----
   *		tell whether to drop the file.
   */
  void
! smgrcreate(Oid relid, SMgrRelation reln, bool isTemp, bool isRedo)
  {
  	XLogRecPtr	lsn;
  	XLogRecData rdata;
*************** smgrcreate(SMgrRelation reln, bool isTem
*** 363,368 ****
--- 364,370 ----
  	/* Add the relation to the list of stuff to delete at abort */
  	pending = (PendingRelDelete *)
  		MemoryContextAlloc(TopMemoryContext, sizeof(PendingRelDelete));
+ 	pending->relid = relid;
  	pending->relnode = reln->smgr_rnode;
  	pending->which = reln->smgr_which;
  	pending->isTemp = isTemp;
*************** smgrcreate(SMgrRelation reln, bool isTem
*** 381,393 ****
   * This also implies smgrclose() on the SMgrRelation object.
   */
  void
! smgrscheduleunlink(SMgrRelation reln, bool isTemp)
  {
  	PendingRelDelete *pending;
  
  	/* Add the relation to the list of stuff to delete at commit */
  	pending = (PendingRelDelete *)
  		MemoryContextAlloc(TopMemoryContext, sizeof(PendingRelDelete));
  	pending->relnode = reln->smgr_rnode;
  	pending->which = reln->smgr_which;
  	pending->isTemp = isTemp;
--- 383,396 ----
   * This also implies smgrclose() on the SMgrRelation object.
   */
  void
! smgrscheduleunlink(Oid relid, SMgrRelation reln, bool isTemp)
  {
  	PendingRelDelete *pending;
  
  	/* Add the relation to the list of stuff to delete at commit */
  	pending = (PendingRelDelete *)
  		MemoryContextAlloc(TopMemoryContext, sizeof(PendingRelDelete));
+ 	pending->relid = relid;
  	pending->relnode = reln->smgr_rnode;
  	pending->which = reln->smgr_which;
  	pending->isTemp = isTemp;
*************** smgrdounlink(SMgrRelation reln, bool isT
*** 430,443 ****
  	/* Close the file and throw away the hashtable entry */
  	smgrclose(reln);
  
! 	smgr_internal_unlink(rnode, which, isTemp, isRedo);
  }
  
  /*
   * Shared subroutine that actually does the unlink ...
   */
  static void
! smgr_internal_unlink(RelFileNode rnode, int which, bool isTemp, bool isRedo)
  {
  	/*
  	 * Get rid of any remaining buffers for the relation.  bufmgr will just
--- 433,446 ----
  	/* Close the file and throw away the hashtable entry */
  	smgrclose(reln);
  
! 	smgr_internal_unlink(InvalidOid, rnode, which, isTemp, isRedo);
  }
  
  /*
   * Shared subroutine that actually does the unlink ...
   */
  static void
! smgr_internal_unlink(Oid relid, RelFileNode rnode, int which, bool isTemp, bool isRedo)
  {
  	/*
  	 * Get rid of any remaining buffers for the relation.  bufmgr will just
*************** smgr_internal_unlink(RelFileNode rnode, 
*** 457,464 ****
  	 * it is, pgstat.c will get confused because we aren't a real backend
  	 * process).
  	 */
! 	if (!InRecovery)
! 		pgstat_drop_relation(rnode.relNode);
  
  	/*
  	 * And delete the physical files.
--- 460,467 ----
  	 * it is, pgstat.c will get confused because we aren't a real backend
  	 * process).
  	 */
! 	if (!InRecovery && OidIsValid(relid))
! 		pgstat_drop_relation(relid);
  
  	/*
  	 * And delete the physical files.
*************** smgrDoPendingDeletes(bool isCommit)
*** 663,669 ****
  				pendingDeletes = next;
  			/* do deletion if called for */
  			if (pending->atCommit == isCommit)
! 				smgr_internal_unlink(pending->relnode,
  									 pending->which,
  									 pending->isTemp,
  									 false);
--- 666,673 ----
  				pendingDeletes = next;
  			/* do deletion if called for */
  			if (pending->atCommit == isCommit)
! 				smgr_internal_unlink(pending->relid,
! 									 pending->relnode,
  									 pending->which,
  									 pending->isTemp,
  									 false);
*************** smgr_redo(XLogRecPtr lsn, XLogRecord *re
*** 804,810 ****
  		SMgrRelation reln;
  
  		reln = smgropen(xlrec->rnode);
! 		smgrcreate(reln, false, true);
  	}
  	else if (info == XLOG_SMGR_TRUNCATE)
  	{
--- 808,814 ----
  		SMgrRelation reln;
  
  		reln = smgropen(xlrec->rnode);
! 		smgrcreate(InvalidOid, reln, false, true);
  	}
  	else if (info == XLOG_SMGR_TRUNCATE)
  	{
diff -cpr head/src/include/storage/smgr.h pgstat_drop_relation/src/include/storage/smgr.h
*** head/src/include/storage/smgr.h	Thu Jan 18 01:25:01 2007
--- pgstat_drop_relation/src/include/storage/smgr.h	Tue Jun 26 19:55:48 2007
*************** extern void smgrsetowner(SMgrRelation *o
*** 63,70 ****
  extern void smgrclose(SMgrRelation reln);
  extern void smgrcloseall(void);
  extern void smgrclosenode(RelFileNode rnode);
! extern void smgrcreate(SMgrRelation reln, bool isTemp, bool isRedo);
! extern void smgrscheduleunlink(SMgrRelation reln, bool isTemp);
  extern void smgrdounlink(SMgrRelation reln, bool isTemp, bool isRedo);
  extern void smgrextend(SMgrRelation reln, BlockNumber blocknum, char *buffer,
  		   bool isTemp);
--- 63,70 ----
  extern void smgrclose(SMgrRelation reln);
  extern void smgrcloseall(void);
  extern void smgrclosenode(RelFileNode rnode);
! extern void smgrcreate(Oid relid, SMgrRelation reln, bool isTemp, bool isRedo);
! extern void smgrscheduleunlink(Oid relid, SMgrRelation reln, bool isTemp);
  extern void smgrdounlink(SMgrRelation reln, bool isTemp, bool isRedo);
  extern void smgrextend(SMgrRelation reln, BlockNumber blocknum, char *buffer,
  		   bool isTemp);