diff -cprN head/src/backend/access/common/reloptions.c fix-relopts/src/backend/access/common/reloptions.c
*** head/src/backend/access/common/reloptions.c	2009-06-11 23:48:53.000000000 +0900
--- fix-relopts/src/backend/access/common/reloptions.c	2009-08-20 09:40:09.900157029 +0900
*************** static relopt_int intRelOpts[] =
*** 108,114 ****
  			"Minimum number of tuple updates or deletes prior to vacuum",
  			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
  		},
! 		50, 0, INT_MAX
  	},
  	{
  		{
--- 108,114 ----
  			"Minimum number of tuple updates or deletes prior to vacuum",
  			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
  		},
! 		-1, 0, INT_MAX
  	},
  	{
  		{
*************** static relopt_int intRelOpts[] =
*** 116,122 ****
  			"Minimum number of tuple inserts, updates or deletes prior to analyze",
  			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
  		},
! 		50, 0, INT_MAX
  	},
  	{
  		{
--- 116,122 ----
  			"Minimum number of tuple inserts, updates or deletes prior to analyze",
  			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
  		},
! 		-1, 0, INT_MAX
  	},
  	{
  		{
*************** static relopt_int intRelOpts[] =
*** 124,130 ****
  			"Vacuum cost delay in milliseconds, for autovacuum",
  			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
  		},
! 		20, 0, 100
  	},
  	{
  		{
--- 124,130 ----
  			"Vacuum cost delay in milliseconds, for autovacuum",
  			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
  		},
! 		-1, 0, 100
  	},
  	{
  		{
*************** static relopt_int intRelOpts[] =
*** 132,138 ****
  			"Vacuum cost amount available before napping, for autovacuum",
  			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
  		},
! 		200, 1, 10000
  	},
  	{
  		{
--- 132,138 ----
  			"Vacuum cost amount available before napping, for autovacuum",
  			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
  		},
! 		-1, 1, 10000
  	},
  	{
  		{
*************** static relopt_int intRelOpts[] =
*** 140,146 ****
  			"Minimum age at which VACUUM should freeze a table row, for autovacuum",
  			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
  		},
! 		100000000, 0, 1000000000
  	},
  	{
  		{
--- 140,146 ----
  			"Minimum age at which VACUUM should freeze a table row, for autovacuum",
  			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
  		},
! 		-1, 0, 1000000000
  	},
  	{
  		{
*************** static relopt_int intRelOpts[] =
*** 148,161 ****
  			"Age at which to autovacuum a table to prevent transaction ID wraparound",
  			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
  		},
! 		200000000, 100000000, 2000000000
  	},
  	{
  		{
  			"autovacuum_freeze_table_age",
  			"Age at which VACUUM should perform a full table sweep to replace old Xid values with FrozenXID",
  			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
! 		}, 150000000, 0, 2000000000
  	},
  	/* list terminator */
  	{{NULL}}
--- 148,161 ----
  			"Age at which to autovacuum a table to prevent transaction ID wraparound",
  			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
  		},
! 		-1, 100000000, 2000000000
  	},
  	{
  		{
  			"autovacuum_freeze_table_age",
  			"Age at which VACUUM should perform a full table sweep to replace old Xid values with FrozenXID",
  			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
! 		}, -1, 0, 2000000000
  	},
  	/* list terminator */
  	{{NULL}}
*************** static relopt_real realRelOpts[] =
*** 169,175 ****
  			"Number of tuple updates or deletes prior to vacuum as a fraction of reltuples",
  			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
  		},
! 		0.2, 0.0, 100.0
  	},
  	{
  		{
--- 169,175 ----
  			"Number of tuple updates or deletes prior to vacuum as a fraction of reltuples",
  			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
  		},
! 		-1, 0.0, 100.0
  	},
  	{
  		{
*************** static relopt_real realRelOpts[] =
*** 177,183 ****
  			"Number of tuple inserts, updates or deletes prior to analyze as a fraction of reltuples",
  			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
  		},
! 		0.1, 0.0, 100.0
  	},
  	/* list terminator */
  	{{NULL}}
--- 177,183 ----
  			"Number of tuple inserts, updates or deletes prior to analyze as a fraction of reltuples",
  			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
  		},
! 		-1, 0.0, 100.0
  	},
  	/* list terminator */
  	{{NULL}}
diff -cprN head/src/backend/postmaster/autovacuum.c fix-relopts/src/backend/postmaster/autovacuum.c
*** head/src/backend/postmaster/autovacuum.c	2009-08-13 05:53:30.000000000 +0900
--- fix-relopts/src/backend/postmaster/autovacuum.c	2009-08-20 10:03:51.979257913 +0900
*************** table_recheck_autovac(Oid relid, HTAB *t
*** 2448,2472 ****
  		 * toast table, try the main table too.  Otherwise use the GUC
  		 * defaults, autovacuum's own first and plain vacuum second.
  		 */
! 		if (avopts)
! 		{
! 			vac_cost_delay = avopts->vacuum_cost_delay;
! 			vac_cost_limit = avopts->vacuum_cost_limit;
! 			freeze_min_age = avopts->freeze_min_age;
! 			freeze_table_age = avopts->freeze_table_age;
! 		}
! 		else
! 		{
! 			/* -1 in autovac setting means use plain vacuum_cost_delay */
! 			vac_cost_delay = autovacuum_vac_cost_delay >= 0 ?
! 				autovacuum_vac_cost_delay : VacuumCostDelay;
! 			/* 0 or -1 in autovac setting means use plain vacuum_cost_limit */
! 			vac_cost_limit = autovacuum_vac_cost_limit > 0 ?
! 				autovacuum_vac_cost_limit : VacuumCostLimit;
! 			/* these do not have autovacuum-specific settings */
! 			freeze_min_age = default_freeze_min_age;
! 			freeze_table_age = default_freeze_table_age;
! 		}
  
  		tab = palloc(sizeof(autovac_table));
  		tab->at_relid = relid;
--- 2448,2476 ----
  		 * toast table, try the main table too.  Otherwise use the GUC
  		 * defaults, autovacuum's own first and plain vacuum second.
  		 */
! 
! 		/* -1 in autovac setting means use plain vacuum_cost_delay */
! 		vac_cost_delay = (avopts && avopts->vacuum_cost_delay >= 0)
! 			? avopts->vacuum_cost_delay
! 			: (autovacuum_vac_cost_delay >= 0)
! 				? autovacuum_vac_cost_delay
! 				: VacuumCostDelay;
! 
! 		/* 0 or -1 in autovac setting means use plain vacuum_cost_limit */
! 		vac_cost_limit = (avopts && avopts->vacuum_cost_limit > 0)
! 			? avopts->vacuum_cost_limit
! 			: (autovacuum_vac_cost_limit > 0)
! 				? autovacuum_vac_cost_limit
! 				: VacuumCostLimit;
! 
! 		/* these do not have autovacuum-specific settings */
! 		freeze_min_age = (avopts && avopts->freeze_min_age >= 0)
! 			? avopts->freeze_min_age
! 			: default_freeze_min_age;
! 
! 		freeze_table_age = (avopts && avopts->freeze_table_age >= 0)
! 			? avopts->freeze_table_age
! 			: default_freeze_table_age;
  
  		tab = palloc(sizeof(autovac_table));
  		tab->at_relid = relid;
*************** relation_needs_vacanalyze(Oid relid,
*** 2563,2587 ****
  	 * sources: the passed reloptions (which could be a main table or a toast
  	 * table), or the autovacuum GUC variables.
  	 */
! 	if (relopts)
! 	{
! 		vac_scale_factor = relopts->vacuum_scale_factor;
! 		vac_base_thresh = relopts->vacuum_threshold;
! 		anl_scale_factor = relopts->analyze_scale_factor;
! 		anl_base_thresh = relopts->analyze_threshold;
! 		freeze_max_age = Min(relopts->freeze_max_age,
! 							 autovacuum_freeze_max_age);
! 		av_enabled = relopts->enabled;
! 	}
! 	else
! 	{
! 		vac_scale_factor = autovacuum_vac_scale;
! 		vac_base_thresh = autovacuum_vac_thresh;
! 		anl_scale_factor = autovacuum_anl_scale;
! 		anl_base_thresh = autovacuum_anl_thresh;
! 		freeze_max_age = autovacuum_freeze_max_age;
! 		av_enabled = true;
! 	}
  
  	/* Force vacuum if table is at risk of wraparound */
  	xidForceLimit = recentXid - freeze_max_age;
--- 2567,2595 ----
  	 * sources: the passed reloptions (which could be a main table or a toast
  	 * table), or the autovacuum GUC variables.
  	 */
! 
! 	/* -1 in autovac setting means use plain vacuum_cost_delay */
! 	vac_scale_factor = (relopts && relopts->vacuum_scale_factor >= 0)
! 		? relopts->vacuum_scale_factor
! 		: autovacuum_vac_scale;
! 
! 	vac_base_thresh = (relopts && relopts->vacuum_threshold >= 0)
! 		? relopts->vacuum_threshold
! 		: autovacuum_vac_thresh;
! 
! 	anl_scale_factor = (relopts && relopts->analyze_scale_factor >= 0)
! 		? relopts->analyze_scale_factor
! 		: autovacuum_anl_scale;
! 
! 	anl_base_thresh = (relopts && relopts->analyze_threshold >= 0)
! 		? relopts->analyze_threshold
! 		: autovacuum_anl_thresh;
! 
! 	freeze_max_age = (relopts && relopts->freeze_max_age >= 0)
! 		? Min(relopts->freeze_max_age, autovacuum_freeze_max_age)
! 		: autovacuum_freeze_max_age;
! 
! 	av_enabled = (relopts ? relopts->enabled : true);
  
  	/* Force vacuum if table is at risk of wraparound */
  	xidForceLimit = recentXid - freeze_max_age;