diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index aa699ae62e14c43009aa7e805358f0e5ae187f15..5ad3aae3aeb49e8da8b921b9262ced29d142e6ab 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.153 2007/06/05 21:31:03 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.154 2007/06/08 21:09:49 alvherre Exp $ -->
 <!--
  Documentation of the system catalogs, directed toward PostgreSQL developers
  -->
@@ -1339,7 +1339,7 @@
    be used for this particular value.  Observe that the
    <structfield>vac_cost_delay</> variable inherits its default value from the
    <xref linkend="guc-autovacuum-vacuum-cost-delay"> configuration parameter,
-   or from <varname>vacuum_cost_delay</> if the former is set to a negative
+   or from <xref linkend="guc-vacuum-cost-delay"> if the former is set to a negative
    value.  The same applies to <structfield>vac_cost_limit</>.
    Also, autovacuum will ignore attempts to set a per-table
    <structfield>freeze_max_age</> larger than the system-wide setting (it can only be set
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index 752af9983131214553689f8d1fab541d449d895c..07bf40707e398f8ec49fc717ea35e6217993118c 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.47 2007/05/30 20:11:57 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.48 2007/06/08 21:09:49 alvherre Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1548,7 +1548,11 @@ static void
 autovac_balance_cost(void)
 {
 	WorkerInfo	worker;
-	int         vac_cost_limit = (autovacuum_vac_cost_limit >= 0 ?
+	/*
+	 * note: in cost_limit, zero also means use value from elsewhere, because
+	 * zero is not a valid value.
+	 */
+	int         vac_cost_limit = (autovacuum_vac_cost_limit > 0 ?
 								  autovacuum_vac_cost_limit : VacuumCostLimit);
 	int         vac_cost_delay = (autovacuum_vac_cost_delay >= 0 ?
 								  autovacuum_vac_cost_delay : VacuumCostDelay);
@@ -2140,12 +2144,14 @@ table_recheck_autovac(Oid relid)
 		 * there is a tuple in pg_autovacuum, use it; else, use the GUC
 		 * defaults.  Note that the fields may contain "-1" (or indeed any
 		 * negative value), which means use the GUC defaults for each setting.
+		 * In cost_limit, the value 0 also means to use the value from
+		 * elsewhere.
 		 */
 		if (avForm != NULL)
 		{
-			vac_cost_limit = (avForm->vac_cost_limit >= 0) ?
+			vac_cost_limit = (avForm->vac_cost_limit > 0) ?
 				avForm->vac_cost_limit :
-				((autovacuum_vac_cost_limit >= 0) ?
+				((autovacuum_vac_cost_limit > 0) ?
 				 autovacuum_vac_cost_limit : VacuumCostLimit);
 
 			vac_cost_delay = (avForm->vac_cost_delay >= 0) ?
@@ -2158,7 +2164,7 @@ table_recheck_autovac(Oid relid)
 		}
 		else
 		{
-			vac_cost_limit = (autovacuum_vac_cost_limit >= 0) ?
+			vac_cost_limit = (autovacuum_vac_cost_limit > 0) ?
 				autovacuum_vac_cost_limit : VacuumCostLimit;
 
 			vac_cost_delay = (autovacuum_vac_cost_delay >= 0) ?