diff -cpr head/src/backend/commands/vacuum.c working/src/backend/commands/vacuum.c
*** head/src/backend/commands/vacuum.c	Sat Jan  6 07:19:26 2007
--- working/src/backend/commands/vacuum.c	Fri Feb  2 11:27:22 2007
*************** full_vacuum_rel(Relation onerel, VacuumS
*** 1207,1213 ****
  
  	/* report results to the stats collector, too */
  	pgstat_report_vacuum(RelationGetRelid(onerel), onerel->rd_rel->relisshared,
! 						 vacstmt->analyze, vacrelstats->rel_tuples);
  }
  
  
--- 1207,1213 ----
  
  	/* report results to the stats collector, too */
  	pgstat_report_vacuum(RelationGetRelid(onerel), onerel->rd_rel->relisshared,
! 						 vacstmt->analyze, vacrelstats->rel_tuples, -1);
  }
  
  
diff -cpr head/src/backend/commands/vacuumlazy.c working/src/backend/commands/vacuumlazy.c
*** head/src/backend/commands/vacuumlazy.c	Sat Jan  6 07:19:27 2007
--- working/src/backend/commands/vacuumlazy.c	Fri Feb  2 11:27:22 2007
*************** lazy_vacuum_rel(Relation onerel, VacuumS
*** 141,146 ****
--- 141,148 ----
  	Relation   *Irel;
  	int			nindexes;
  	BlockNumber possibly_freeable;
+ 	PgStat_StatTabEntry	   *stat_table;
+ 	PgStat_Counter			n_dead_duples_at_start;
  
  	if (vacstmt->verbose)
  		elevel = INFO;
*************** lazy_vacuum_rel(Relation onerel, VacuumS
*** 150,155 ****
--- 152,163 ----
  	vacuum_set_xid_limits(vacstmt, onerel->rd_rel->relisshared,
  						  &OldestXmin, &FreezeLimit);
  
+ 	stat_table = pgstat_fetch_stat_tabentry(RelationGetRelid(onerel));
+ 	if (stat_table != NULL)
+ 		n_dead_duples_at_start = stat_table->n_dead_tuples;
+ 	else
+ 		n_dead_duples_at_start = 0;
+ 
  	vacrelstats = (LVRelStats *) palloc0(sizeof(LVRelStats));
  
  	/* Set threshold for interesting free space = average request size */
*************** lazy_vacuum_rel(Relation onerel, VacuumS
*** 189,195 ****
  
  	/* report results to the stats collector, too */
  	pgstat_report_vacuum(RelationGetRelid(onerel), onerel->rd_rel->relisshared,
! 						 vacstmt->analyze, vacrelstats->rel_tuples);
  }
  
  
--- 197,204 ----
  
  	/* report results to the stats collector, too */
  	pgstat_report_vacuum(RelationGetRelid(onerel), onerel->rd_rel->relisshared,
! 						 vacstmt->analyze, vacrelstats->rel_tuples,
! 						 n_dead_duples_at_start);
  }
  
  
diff -cpr head/src/backend/postmaster/pgstat.c working/src/backend/postmaster/pgstat.c
*** head/src/backend/postmaster/pgstat.c	Sat Jan 27 05:06:52 2007
--- working/src/backend/postmaster/pgstat.c	Fri Feb  2 11:27:22 2007
*************** pgstat_report_autovac(Oid dboid)
*** 914,924 ****
   * pgstat_report_vacuum() -
   *
   *	Tell the collector about the table we just vacuumed.
   * ---------
   */
  void
! pgstat_report_vacuum(Oid tableoid, bool shared,
! 					 bool analyze, PgStat_Counter tuples)
  {
  	PgStat_MsgVacuum msg;
  
--- 914,925 ----
   * pgstat_report_vacuum() -
   *
   *	Tell the collector about the table we just vacuumed.
+  *	deleted_tuples < 0 means all dead tuples have been removed.
   * ---------
   */
  void
! pgstat_report_vacuum(Oid tableoid, bool shared, bool analyze,
! 					 PgStat_Counter tuples, PgStat_Counter deleted_tuples)
  {
  	PgStat_MsgVacuum msg;
  
*************** pgstat_report_vacuum(Oid tableoid, bool 
*** 933,938 ****
--- 934,940 ----
  	msg.m_autovacuum = IsAutoVacuumProcess();	/* is this autovacuum? */
  	msg.m_vacuumtime = GetCurrentTimestamp();
  	msg.m_tuples = tuples;
+ 	msg.m_deleted_tuples = deleted_tuples;
  	pgstat_send(&msg, sizeof(msg));
  }
  
*************** pgstat_recv_vacuum(PgStat_MsgVacuum *msg
*** 2568,2574 ****
  	else
  		tabentry->vacuum_timestamp = msg->m_vacuumtime;
  	tabentry->n_live_tuples = msg->m_tuples;
! 	tabentry->n_dead_tuples = 0;
  	if (msg->m_analyze)
  	{
  		tabentry->last_anl_tuples = msg->m_tuples;
--- 2570,2580 ----
  	else
  		tabentry->vacuum_timestamp = msg->m_vacuumtime;
  	tabentry->n_live_tuples = msg->m_tuples;
! 	if (msg->m_deleted_tuples < 0 ||
! 		tabentry->n_dead_tuples < msg->m_deleted_tuples)
! 		tabentry->n_dead_tuples = 0;
! 	else
! 		tabentry->n_dead_tuples -= msg->m_deleted_tuples;
  	if (msg->m_analyze)
  	{
  		tabentry->last_anl_tuples = msg->m_tuples;
diff -cpr head/src/include/pgstat.h working/src/include/pgstat.h
*** head/src/include/pgstat.h	Sat Jan  6 07:19:50 2007
--- working/src/include/pgstat.h	Fri Feb  2 11:27:22 2007
*************** typedef struct PgStat_MsgVacuum
*** 192,197 ****
--- 192,198 ----
  	bool		m_autovacuum;
  	TimestampTz m_vacuumtime;
  	PgStat_Counter m_tuples;
+ 	PgStat_Counter m_deleted_tuples;
  } PgStat_MsgVacuum;
  
  
*************** extern void pgstat_drop_relation(Oid rel
*** 383,390 ****
  extern void pgstat_reset_counters(void);
  
  extern void pgstat_report_autovac(Oid dboid);
! extern void pgstat_report_vacuum(Oid tableoid, bool shared,
! 					 bool analyze, PgStat_Counter tuples);
  extern void pgstat_report_analyze(Oid tableoid, bool shared,
  					  PgStat_Counter livetuples,
  					  PgStat_Counter deadtuples);
--- 384,391 ----
  extern void pgstat_reset_counters(void);
  
  extern void pgstat_report_autovac(Oid dboid);
! extern void pgstat_report_vacuum(Oid tableoid, bool shared, bool analyze,
! 					 PgStat_Counter tuples, PgStat_Counter deleted_tuples);
  extern void pgstat_report_analyze(Oid tableoid, bool shared,
  					  PgStat_Counter livetuples,
  					  PgStat_Counter deadtuples);