diff --git a/contrib/Makefile b/contrib/Makefile
index 971afe6dfeffd1f633a12c12a19e8f63b3fc33f3..cec541490f3ba744445e025a3b80665b9d7f48b0 100644
--- a/contrib/Makefile
+++ b/contrib/Makefile
@@ -1,4 +1,4 @@
-# $PostgreSQL: pgsql/contrib/Makefile,v 1.59 2005/07/29 15:13:10 momjian Exp $
+# $PostgreSQL: pgsql/contrib/Makefile,v 1.60 2005/07/29 19:38:21 tgl Exp $
 
 subdir = contrib
 top_builddir = ..
@@ -20,7 +20,6 @@ WANTED_DIRS = \
 		lo		\
 		ltree		\
 		oid2name	\
-		pg_autovacuum	\
 		pg_buffercache	\
 		pg_trgm		\
 		pgbench		\
diff --git a/contrib/README b/contrib/README
index e1e9a593c7e9266678b434b01d725792a3cb74e6..17e07d7f6ae1cc01bcd58dc270423a86d1dc7fe7 100644
--- a/contrib/README
+++ b/contrib/README
@@ -102,10 +102,6 @@ oracle -
 	Converts Oracle database schema to PostgreSQL
 	by Gilles Darold <gilles@darold.net>
 
-pg_autovacuum -
-	Automatically performs vacuum
-	by Matthew T. O'Connor <matthew@zeut.net>
-
 pg_buffercache -
 	Real time queries on the shared buffer cache
 	by Mark Kirkwood <markir@paradise.net.nz>
@@ -142,7 +138,7 @@ tablefunc -
 	Examples of functions returning tables
 	by Joe Conway <mail@joeconway.com>
 
-tips/apache_logging -
+tips -
 	Getting Apache to log to PostgreSQL
 	by Terry Mackintosh <terry@terrym.com>
 
diff --git a/contrib/pg_autovacuum/Makefile b/contrib/pg_autovacuum/Makefile
deleted file mode 100644
index c512d18b7efe98ee0fa3fac7af62f0c98cec26ad..0000000000000000000000000000000000000000
--- a/contrib/pg_autovacuum/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-PROGRAM = pg_autovacuum
-OBJS	= pg_autovacuum.o dllist.o
-
-PG_CPPFLAGS = -I$(libpq_srcdir) -DFRONTEND
-PG_LIBS = $(libpq_pgport)
-
-DOCS = README.pg_autovacuum
-
-EXTRA_CLEAN = dllist.c
-
-ifdef USE_PGXS
-PGXS = $(shell pg_config --pgxs)
-include $(PGXS)
-else
-subdir = contrib/pg_autovacuum
-top_builddir = ../..
-include $(top_builddir)/src/Makefile.global
-include $(top_srcdir)/contrib/contrib-global.mk
-endif
-
-dllist.c: $(top_srcdir)/src/backend/lib/dllist.c
-	rm -f $@ && $(LN_S) $< .
diff --git a/contrib/pg_autovacuum/README.pg_autovacuum b/contrib/pg_autovacuum/README.pg_autovacuum
deleted file mode 100644
index f20842135b8af81ff1a7de261f2055ec6924876a..0000000000000000000000000000000000000000
--- a/contrib/pg_autovacuum/README.pg_autovacuum
+++ /dev/null
@@ -1,246 +0,0 @@
-pg_autovacuum README
---------------------
-
-pg_autovacuum is a libpq client program that monitors all the
-databases associated with a PostgreSQL server.  It uses the statistics
-collector to monitor insert, update and delete activity.  
-
-When a table exceeds a insert or delete threshold (for more detail on
-thresholds, see "Vacuum and Analyze" below) then that table will be
-vacuumed and/or analyzed.
-
-This allows PostgreSQL to keep the FSM (Free Space Map) and table
-statistics up to date, and eliminates the need to schedule periodic
-vacuums.
-
-The primary benefit of pg_autovacuum is that the FSM and table
-statistic information are updated more nearly as frequently as needed.
-When a table is actively changing, pg_autovacuum will perform the
-VACUUMs and ANALYZEs that such a table needs, whereas if a table
-remains static, no cycles will be wasted performing this
-unnecessarily.
-
-A secondary benefit of pg_autovacuum is that it ensures that a
-database wide vacuum is performed prior to XID wraparound.  This is an
-important, if rare, problem, as failing to do so can result in major
-data loss.  (See the section in the _Administrator's Guide_ entitled
-"Preventing transaction ID wraparound failures" for more details.)
-
-KNOWN ISSUES:
--------------
-
-pg_autovacuum has been tested under Redhat Linux (by me) and Debian
-GNU/Linux, Solaris, and AIX (by Christopher B. Browne) and all known
-bugs have been resolved.  Please report any problems to the hackers
-list.
-
-pg_autovacuum requires that the statistics system be enabled and
-reporting row level stats.  The overhead of the stats system has been
-shown to be significant under certain workloads.  For instance, a
-tight loop of queries performing "select 1" was found to run nearly
-30% slower when row-level stats were enabled.  However, in practice,
-with more realistic workloads, the stats system overhead is usually
-nominal.
-
-pg_autovacuum does not get started automatically by either the
-postmaster or by pg_ctl.  Similarly, when the postmaster exits, no one
-tells pg_autovacuum.  The result of that is that at the start of the
-next loop, pg_autovacuum will fail to connect to the server and
-exit().  Any time it fails to connect pg_autovacuum exit()s.
-
-While pg_autovacuum can manage vacuums for as many databases as you
-may have tied to a particular PostgreSQL postmaster, it can only
-connect to a single PostgreSQL postmaster.  Thus, if you have multiple
-postmasters on a particular host, you will need multiple pg_autovacuum
-instances, and they have no way, at present, to coordinate between one
-another to ensure that they do not concurrently vacuum big tables.
-
-When installed as a service under Windows, there is currently no way to
-know the name of the PostgreSQL server service (if there even is one)
-so it is not possible to specify a startup dependency. It is therefore
-possible for pg_autovacuum to start before the server.
-
-When installed as a service under Windows, if the -P option is used to
-specify the connection password, this option (and the password) is 
-stored in plain text in the registry.
-
-TODO:
------
-
-At present, there are no sample scripts to automatically start up
-pg_autovacuum along with the database.  It would be desirable to have
-a SysV script to start up pg_autovacuum after PostgreSQL has been
-started.
-
-Some users have expressed interest in making pg_autovacuum more
-configurable so that certain tables known to be inactive could be
-excluded from being vacuumed.  It would probably make sense to
-introduce this sort of functionality by providing arguments to specify
-the database and schema in which to find a configuration table.
-
-It would also be desirable for the daemon to monitor how busy the
-system is, with a view to deferring vacuums until there is less other
-activity.
-
-INSTALL:
---------
-
-As of postgresql v7.4 pg_autovacuum is included in the main source
-tree under contrib.  Therefore you merely need to "make && make
-install" (similar to most other contrib modules) and it will be
-installed for you.
-
-If you are using an earlier version of PostgreSQL, uncompress the
-tar.gz file into the contrib directory and modify the contrib/Makefile
-to include the pg_autovacuum directory.  pg_autovacuum will then be
-built as part of the standard postgresql install.  It is known to work
-with v7.3 releases; it is not presently compatible with v7.2.
-
-make sure that the following are set in postgresql.conf:
-
-  stats_start_collector = true
-  stats_row_level = true
-
-Start up the postmaster, then execute the pg_autovacuum executable.
-
-If you have a script that automatically starts up the PostgreSQL
-instance, you might add in, after that, something similar to the
-following:
-
-  sleep 10    # To give the database some time to start up
-  $PGBINS/pg_autovacuum -D -s $SBASE -S $SSCALE ... [other arguments]
-
-Command line arguments:
------------------------
-
-pg_autovacuum has the following optional arguments:
-
--d debug: 0 silent, 1 basic info, 2 more debug info,  etc...
--D daemonize: Detach from tty and run in background.
--s sleep base value: see "Sleeping" below.
--S sleep scaling factor: see "Sleeping" below.
--v vacuum base threshold: see "Vacuum and Analyze" below.
--V vacuum scaling factor: see "Vacuum and Analyze" below.
--a analyze base threshold: see "Vacuum and Analyze" below.
--A analyze scaling factor: see "Vacuum and Analyze" below.
--i update interval: how often (in terms of iterations of the primary loop
-   over the database list) to update the database list. The default is 2,
-   which means the list will be updated before every other pass through
-   the database list.
--L log file: Name of file to which output is submitted, otherwise STDERR
--U username: Username pg_autovacuum will use to connect with, if not
-   specified the current username is used.
--P password: Password pg_autovacuum will use to connect with. *WARNING*
-   This option is insecure. When installed as a Windows Service, this
-   option will be stored in plain text in the registry. When used with
-   most Unix variants, other users will be able to see the argument to
-   the "-P" option via ps(1). The ~/.pgpass file can be used to
-   specify a password more securely.
--H host: host name or IP to connect to.
--p port: port used for connection.
--h help: list of command line options.
-
-The following 5 autovacuum command line options correspond to the various
-cost-based vacuum settings.  If not given, then the cluster default values
-will be used.
-
--c	vacuum_cost_delay
--C	vacuum_cost_page_hit
--m	vacuum_cost_page_miss
--n	vacuum_cost_page_dirty
--l	vacuum_cost_limit
-
-
-Numerous arguments have default values defined in pg_autovacuum.h.  At
-the time of writing they are:
-
--d 1
--v 1000
--V 2   
--a 500 (half of -v if not specified)
--A 1   (half of -V if not specified)
--s 300 (5 minutes)
--S 2
--i 2
-
-The following arguments are used on Windows only:
-
--I Install the executable as a Windows service. Other appropriate command
-   line options will be stored in the registry and passed to the service 
-   at startup. *WARNING* This includes the connection password which will 
-   be stored in plain text.
-	     
--N service user: Name of the Windows user account under which the service
-   will run. Only used when installing as a Windows service.
-   
--W service password: The password for the service account. Only used when 
-   installing as a Windows service.
-
--R Uninstall pg_autovacuum as a service.
-
--E Dependent service that must start before this service. Normally this will be
-   a PostgreSQL instance, e.g. "-E pgsql-8.0.0". Only used when installing as 
-   a Windows service.
-
-Vacuum and Analyze:
--------------------
-
-pg_autovacuum performs either a VACUUM ANALYZE or just ANALYZE
-depending on the mixture of table activity (insert, update, or
-delete):
-
-- If the number of (inserts + updates + deletes) > AnalyzeThreshold, then
-  only an analyze is performed.
-
-- If the number of (deletes + updates) > VacuumThreshold, then a
-  vacuum analyze is performed.
-
-VacuumThreshold is equal to:
-    vacuum_base_value + (vacuum_scaling_factor * "number of tuples in the table")
-
-AnalyzeThreshold is equal to:
-    analyze_base_value + (analyze_scaling_factor * "number of tuples in the table")
-
-The AnalyzeThreshold defaults to half of the VacuumThreshold since it
-represents a much less expensive operation (approx 5%-10% of vacuum),
-and running ANALYZE more often should not substantially degrade system
-performance.
-
-Sleeping:
----------
-
-pg_autovacuum sleeps for a while after it is done checking all the
-databases.  It does this in order to limit the amount of system
-resources it consumes.  This allows the system administrator to
-configure pg_autovacuum to be more or less aggressive.
-
-Reducing the sleep time will cause pg_autovacuum to respond more
-quickly to changes, whether they be database addition/removal, table
-addition/removal, or just normal table activity.
-
-On the other hand, setting pg_autovacuum to sleep values too
-aggressively (to too short periods of time) can have a negative effect
-on server performance.  For instance, if a table gets vacuumed 5 times
-during the course of a large set of updates, this is likely to take a
-lot more work than if the table was vacuumed just once, at the end.
-
-The total time it sleeps is equal to:
-
-  base_sleep_value + sleep_scaling_factor * "duration of the previous
-  loop"
-
-Note that timing measurements are made in seconds; specifying
-"pg_vacuum -s 1" means pg_autovacuum could poll the database up to 60
-times minute.  In a system with large tables where vacuums may run for
-several minutes, rather longer times between vacuums are likely to be
-appropriate.
-
-What pg_autovacuum monitors:
-----------------------------
-
-pg_autovacuum dynamically generates a list of all databases and tables
-that exist on the server.  It will dynamically add and remove
-databases and tables that are removed from the database server while
-pg_autovacuum is running.  Overhead is fairly small per object.  For
-example: 10 databases with 10 tables each appears to less than 10k of
-memory on my Linux box.
diff --git a/contrib/pg_autovacuum/TODO b/contrib/pg_autovacuum/TODO
deleted file mode 100644
index b93f2e24943ee835fa1253758fbb8ee492b52e0e..0000000000000000000000000000000000000000
--- a/contrib/pg_autovacuum/TODO
+++ /dev/null
@@ -1,45 +0,0 @@
-Todo Items for pg_autovacuum client
---------------------------------------------------------------------------
-
-_Add Startup Message (with datetime stamp) to Logfile when starting and logging 
-
-_create a FSM export function and see if I can use it for pg_autovacuum
-
-_look into possible benifits of pgstattuple contrib work
-
-_Continue trying to reduce server load created by polling.
-
-Done:
---------------------------------------------------------------------------
-_Check if required pg_stats are enables, if not exit with error
-
-_Reduce the number connections and queries to the server
-	_Make database adding and removal part of the normal loop
-	_make table adding and removal part of the normal loop
-
-_Separate logic for vacuum and analyze
-
-_all pg_autovacuum specific functions are now static
-
-_correct usage of snprintf
-
-_reworked database and table update functions, now they
-	use the existing database connection and only one query
-
-_fixed -h option output
-
-_cleanup of 'constant == variable' used much more consistently now.
-
-_Guarantee database wide vacuum prior to Xid wraparound
-
-_change name to pg_autovacuum
-
-_Add proper table and database removal functions so that we can properly
-	clear up before we exit, and make sure we don't leak memory when removing tables and such.
-
-_Decouple insert and delete thresholds
-
-_Fix Vacuum debug routine to include the database name.
-
-_Allow it to detach from the tty
-
diff --git a/contrib/pg_autovacuum/pg_autovacuum.c b/contrib/pg_autovacuum/pg_autovacuum.c
deleted file mode 100644
index 36b10d657bf2b0d7d6731ff708ae4336d15c9227..0000000000000000000000000000000000000000
--- a/contrib/pg_autovacuum/pg_autovacuum.c
+++ /dev/null
@@ -1,1862 +0,0 @@
-/* pg_autovacuum.c
- * All the code for the pg_autovacuum program
- * (c) 2003 Matthew T. O'Connor
- * Revisions by Christopher B. Browne, Liberty RMS
- * Win32 Service code added by Dave Page
- *
- * $PostgreSQL: pgsql/contrib/pg_autovacuum/pg_autovacuum.c,v 1.35 2005/06/15 13:55:23 momjian Exp $
- */
-
-#include "postgres_fe.h"
-
-#include <unistd.h>
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#endif
-#include <time.h>
-#include <sys/time.h>
-#ifdef WIN32
-#include <windows.h>
-#endif
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "pg_autovacuum.h"
-
-#ifdef WIN32
-SERVICE_STATUS ServiceStatus;
-SERVICE_STATUS_HANDLE hStatus;
-int			appMode = 0;
-char       deps[255];
-#endif
-
-/* define atooid */
-#define atooid(x)  ((Oid) strtoul((x), NULL, 10))
-
-
-static cmd_args *args;
-static FILE	   *LOGOUTPUT;
-static char		logbuffer[4096];
-
-
-/* The main program loop function */
-static int	VacuumLoop(int argc, char **argv);
-
-/* Functions for dealing with command line arguements */
-static cmd_args *get_cmd_args(int argc, char *argv[]);
-static void print_cmd_args(void);
-static void free_cmd_args(void);
-static void usage(void);
-
-/* Functions for managing database lists */
-static Dllist *init_db_list(void);
-static db_info *init_dbinfo(char *dbname, Oid oid, long age);
-static void update_db_list(Dllist *db_list);
-static void remove_db_from_list(Dlelem *db_to_remove);
-static void print_db_info(db_info * dbi, int print_table_list);
-static void print_db_list(Dllist *db_list, int print_table_lists);
-static int	xid_wraparound_check(db_info * dbi);
-static void free_db_list(Dllist *db_list);
-
-/* Functions for managing table lists */
-static tbl_info *init_table_info(PGresult *conn, int row, db_info * dbi);
-static void update_table_list(db_info * dbi);
-static void remove_table_from_list(Dlelem *tbl_to_remove);
-static void print_table_list(Dllist *tbl_node);
-static void print_table_info(tbl_info * tbl);
-static void update_table_thresholds(db_info * dbi, tbl_info * tbl, int vacuum_type);
-static void free_tbl_list(Dllist *tbl_list);
-
-/* A few database helper functions */
-static int	check_stats_enabled(db_info * dbi);
-static PGconn *db_connect(db_info * dbi);
-static void db_disconnect(db_info * dbi);
-static PGresult *send_query(const char *query, db_info * dbi);
-
-/* Other Generally needed Functions */
-#ifndef WIN32
-static void daemonize(void);
-#endif
-static void log_entry(const char *logentry, int level);
-
-#ifdef WIN32
-/* Windows Service related functions */
-static void ControlHandler(DWORD request);
-static int	InstallService();
-static int	RemoveService();
-#endif
-
-
-static void
-log_entry(const char *logentry, int level)
-{
-	/*
-	 * Note: Under Windows we dump the log entries to the normal
-	 * stderr/logfile as well, otherwise it can be a pain to debug
-	 * service install failures etc.
-	 */
-
-	time_t		curtime;
-	struct tm  *loctime;
-	char		timebuffer[128],
-				slevel[10];
-
-
-#ifdef WIN32
-	static HANDLE evtHandle = INVALID_HANDLE_VALUE;
-	static int	last_level;
-	WORD		elevel;
-#endif
-
-	switch (level)
-	{
-		case LVL_DEBUG:
-			sprintf(slevel, "DEBUG:   ");
-			break;
-
-		case LVL_INFO:
-			sprintf(slevel, "INFO:    ");
-			break;
-
-		case LVL_WARNING:
-			sprintf(slevel, "WARNING: ");
-			break;
-
-		case LVL_ERROR:
-			sprintf(slevel, "ERROR:   ");
-			break;
-
-		case LVL_EXTRA:
-			sprintf(slevel, "         ");
-			break;
-
-		default:
-			sprintf(slevel, "         ");
-			break;
-	}
-
-	curtime = time(NULL);
-	loctime = localtime(&curtime);
-	strftime(timebuffer, sizeof(timebuffer), "%Y-%m-%d %H:%M:%S %Z", loctime);
-	fprintf(LOGOUTPUT, "[%s] %s%s\n", timebuffer, slevel, logentry);
-
-#ifdef WIN32
-
-	/* Restore the previous level if this is extra info */
-	if (level == LVL_EXTRA)
-		level = last_level;
-	last_level = level;
-
-	switch (level)
-	{
-		case LVL_DEBUG:
-			elevel = EVENTLOG_INFORMATION_TYPE;
-			break;
-
-		case LVL_INFO:
-			elevel = EVENTLOG_SUCCESS;
-			break;
-
-		case LVL_WARNING:
-			elevel = EVENTLOG_WARNING_TYPE;
-			break;
-
-		case LVL_ERROR:
-			elevel = EVENTLOG_ERROR_TYPE;
-			break;
-
-		default:
-			elevel = EVENTLOG_SUCCESS;
-			break;
-	}
-
-	if (evtHandle == INVALID_HANDLE_VALUE)
-	{
-		evtHandle = RegisterEventSource(NULL, "PostgreSQL Auto Vacuum");
-		if (evtHandle == NULL)
-		{
-			evtHandle = INVALID_HANDLE_VALUE;
-			return;
-		}
-	}
-
-	ReportEvent(evtHandle, elevel, 0, 0, NULL, 1, 0, &logentry, NULL);
-#endif
-}
-
-/*
- * Function used to detach the pg_autovacuum daemon from the tty and go into
- * the background.
- *
- * This code is ripped directly from pmdaemonize in postmaster.c.
- */
-#ifndef WIN32
-static void
-daemonize(void)
-{
-	int			i;
-	pid_t		pid;
-
-	pid = fork();
-	if (pid == (pid_t) -1)
-	{
-		log_entry("cannot disassociate from controlling TTY", LVL_ERROR);
-		fflush(LOGOUTPUT);
-		_exit(1);
-	}
-	else if (pid)
-	{							/* parent */
-		/* Parent should just exit, without doing any atexit cleanup */
-		_exit(0);
-	}
-
-/* GH: If there's no setsid(), we hopefully don't need silent mode.
- * Until there's a better solution.
- */
-#ifdef HAVE_SETSID
-	if (setsid() < 0)
-	{
-		log_entry("cannot disassociate from controlling TTY", LVL_ERROR);
-		fflush(LOGOUTPUT);
-		_exit(1);
-	}
-#endif
-	i = open(NULL_DEV, O_RDWR);
-	dup2(i, 0);
-	dup2(i, 1);
-	dup2(i, 2);
-	close(i);
-}
-#endif   /* WIN32 */
-
-/* Create and return tbl_info struct with initialized to values from row or res */
-static tbl_info *
-init_table_info(PGresult *res, int row, db_info * dbi)
-{
-	tbl_info   *new_tbl = (tbl_info *) malloc(sizeof(tbl_info));
-
-	if (!new_tbl)
-	{
-		log_entry("init_table_info: Cannot get memory", LVL_ERROR);
-		fflush(LOGOUTPUT);
-		return NULL;
-	}
-
-	if (res == NULL)
-		return NULL;
-
-	new_tbl->dbi = dbi;			/* set pointer to db */
-
-	new_tbl->schema_name = (char *)
-		malloc(strlen(PQgetvalue(res, row, PQfnumber(res, "schemaname"))) + 1);
-	if (!new_tbl->schema_name)
-	{
-		log_entry("init_table_info: malloc failed on new_tbl->schema_name", LVL_ERROR);
-		fflush(LOGOUTPUT);
-		return NULL;
-	}
-	strcpy(new_tbl->schema_name,
-		   PQgetvalue(res, row, PQfnumber(res, "schemaname")));
-
-	new_tbl->table_name = (char *)
-		malloc(strlen(PQgetvalue(res, row, PQfnumber(res, "relname"))) +
-			   strlen(new_tbl->schema_name) + 6);
-	if (!new_tbl->table_name)
-	{
-		log_entry("init_table_info: malloc failed on new_tbl->table_name", LVL_ERROR);
-		fflush(LOGOUTPUT);
-		return NULL;
-	}
-
-	/*
-	 * Put both the schema and table name in quotes so that we can work
-	 * with mixed case table names
-	 */
-	strcpy(new_tbl->table_name, "\"");
-	strcat(new_tbl->table_name, new_tbl->schema_name);
-	strcat(new_tbl->table_name, "\".\"");
-	strcat(new_tbl->table_name, PQgetvalue(res, row, PQfnumber(res, "relname")));
-	strcat(new_tbl->table_name, "\"");
-
-	new_tbl->CountAtLastAnalyze =
-		(atol(PQgetvalue(res, row, PQfnumber(res, "n_tup_ins"))) +
-		 atol(PQgetvalue(res, row, PQfnumber(res, "n_tup_upd"))) +
-		 atol(PQgetvalue(res, row, PQfnumber(res, "n_tup_del"))));
-	new_tbl->curr_analyze_count = new_tbl->CountAtLastAnalyze;
-
-	new_tbl->CountAtLastVacuum =
-		(atol(PQgetvalue(res, row, PQfnumber(res, "n_tup_del"))) +
-		 atol(PQgetvalue(res, row, PQfnumber(res, "n_tup_upd"))));
-	new_tbl->curr_vacuum_count = new_tbl->CountAtLastVacuum;
-
-	new_tbl->relid = atooid(PQgetvalue(res, row, PQfnumber(res, "oid")));
-	new_tbl->reltuples = atof(PQgetvalue(res, row, PQfnumber(res, "reltuples")));
-	new_tbl->relpages = atooid(PQgetvalue(res, row, PQfnumber(res, "relpages")));
-
-	if (strcmp("t", PQgetvalue(res, row, PQfnumber(res, "relisshared"))))
-		new_tbl->relisshared = 0;
-	else
-		new_tbl->relisshared = 1;
-
-	new_tbl->analyze_threshold =
-		args->analyze_base_threshold + args->analyze_scaling_factor * new_tbl->reltuples;
-	new_tbl->vacuum_threshold =
-		args->vacuum_base_threshold + args->vacuum_scaling_factor * new_tbl->reltuples;
-
-	if (args->debug >= 2)
-		print_table_info(new_tbl);
-
-	return new_tbl;
-}
-
-/* Set thresholds = base_value + scaling_factor * reltuples
-   Should be called after a vacuum since vacuum updates values in pg_class */
-static void
-update_table_thresholds(db_info * dbi, tbl_info * tbl, int vacuum_type)
-{
-	PGresult   *res = NULL;
-	int			disconnect = 0;
-	char		query[128];
-
-	if (dbi->conn == NULL)
-	{
-		dbi->conn = db_connect(dbi);
-		disconnect = 1;
-	}
-
-	if (dbi->conn != NULL)
-	{
-		snprintf(query, sizeof(query), PAGES_QUERY, tbl->relid);
-		res = send_query(query, dbi);
-		if (res != NULL)
-		{
-			tbl->reltuples =
-				atof(PQgetvalue(res, 0, PQfnumber(res, "reltuples")));
-			tbl->relpages = atooid(PQgetvalue(res, 0, PQfnumber(res, "relpages")));
-
-			/*
-			 * update vacuum thresholds only of we just did a vacuum
-			 * analyze
-			 */
-			if (vacuum_type == VACUUM_ANALYZE)
-			{
-				tbl->vacuum_threshold =
-					(args->vacuum_base_threshold + args->vacuum_scaling_factor * tbl->reltuples);
-				tbl->CountAtLastVacuum = tbl->curr_vacuum_count;
-			}
-
-			/* update analyze thresholds */
-			tbl->analyze_threshold =
-				(args->analyze_base_threshold + args->analyze_scaling_factor * tbl->reltuples);
-			tbl->CountAtLastAnalyze = tbl->curr_analyze_count;
-
-			PQclear(res);
-
-			/*
-			 * If the stats collector is reporting fewer updates then we
-			 * have on record then the stats were probably reset, so we
-			 * need to reset also
-			 */
-			if ((tbl->curr_analyze_count < tbl->CountAtLastAnalyze) ||
-				(tbl->curr_vacuum_count < tbl->CountAtLastVacuum))
-			{
-				tbl->CountAtLastAnalyze = tbl->curr_analyze_count;
-				tbl->CountAtLastVacuum = tbl->curr_vacuum_count;
-			}
-		}
-	}
-	if (disconnect)
-		db_disconnect(dbi);
-}
-
-static void
-update_table_list(db_info * dbi)
-{
-	int			disconnect = 0;
-	PGresult   *res = NULL;
-	tbl_info   *tbl = NULL;
-	Dlelem	   *tbl_elem = DLGetHead(dbi->table_list);
-	int			i = 0,
-				t = 0,
-				found_match = 0;
-
-	if (dbi->conn == NULL)
-	{
-		dbi->conn = db_connect(dbi);
-		disconnect = 1;
-	}
-
-	if (dbi->conn != NULL)
-	{
-		/*
-		 * Get a result set that has all the information we will need to
-		 * both remove tables from the list that no longer exist and add
-		 * tables to the list that are new
-		 */
-		res = send_query((char *) TABLE_STATS_QUERY, dbi);
-		if (res != NULL)
-		{
-			t = PQntuples(res);
-
-			/*
-			 * First: use the tbl_list as the outer loop and the result
-			 * set as the inner loop, this will determine what tables
-			 * should be removed
-			 */
-			while (tbl_elem != NULL)
-			{
-				tbl = ((tbl_info *) DLE_VAL(tbl_elem));
-				found_match = 0;
-
-				for (i = 0; i < t; i++)
-				{				/* loop through result set looking for a
-								 * match */
-					if (tbl->relid == atooid(PQgetvalue(res, i, PQfnumber(res, "oid"))))
-					{
-						found_match = 1;
-						break;
-					}
-				}
-				if (found_match == 0)
-				{				/* then we didn't find this tbl_elem in
-								 * the result set */
-					Dlelem	   *elem_to_remove = tbl_elem;
-
-					tbl_elem = DLGetSucc(tbl_elem);
-					remove_table_from_list(elem_to_remove);
-				}
-				else
-					tbl_elem = DLGetSucc(tbl_elem);
-			}					/* Done removing dropped tables from the
-								 * table_list */
-
-			/*
-			 * Then loop use result set as outer loop and tbl_list as the
-			 * inner loop to determine what tables are new
-			 */
-			for (i = 0; i < t; i++)
-			{
-				tbl_elem = DLGetHead(dbi->table_list);
-				found_match = 0;
-				while (tbl_elem != NULL)
-				{
-					tbl = ((tbl_info *) DLE_VAL(tbl_elem));
-					if (tbl->relid == atooid(PQgetvalue(res, i, PQfnumber(res, "oid"))))
-					{
-						found_match = 1;
-						break;
-					}
-					tbl_elem = DLGetSucc(tbl_elem);
-				}
-				if (found_match == 0)	/* then we didn't find this result
-										 * now in the tbl_list */
-				{
-					DLAddTail(dbi->table_list, DLNewElem(init_table_info(res, i, dbi)));
-					if (args->debug >= 1)
-					{
-						sprintf(logbuffer, "added table: %s.%s", dbi->dbname,
-								((tbl_info *) DLE_VAL(DLGetTail(dbi->table_list)))->table_name);
-						log_entry(logbuffer, LVL_DEBUG);
-					}
-				}
-			}					/* end of for loop that adds tables */
-		}
-		fflush(LOGOUTPUT);
-		PQclear(res);
-		res = NULL;
-		if (args->debug >= 3)
-			print_table_list(dbi->table_list);
-		if (disconnect)
-			db_disconnect(dbi);
-	}
-}
-
-/* Free memory, and remove the node from the list */
-static void
-remove_table_from_list(Dlelem *tbl_to_remove)
-{
-	tbl_info   *tbl = ((tbl_info *) DLE_VAL(tbl_to_remove));
-
-	if (args->debug >= 1)
-	{
-		sprintf(logbuffer, "Removing table: %s.%s from list.", tbl->dbi->dbname, tbl->table_name);
-		log_entry(logbuffer, LVL_DEBUG);
-		fflush(LOGOUTPUT);
-	}
-	DLRemove(tbl_to_remove);
-
-	if (tbl->schema_name)
-	{
-		free(tbl->schema_name);
-		tbl->schema_name = NULL;
-	}
-	if (tbl->table_name)
-	{
-		free(tbl->table_name);
-		tbl->table_name = NULL;
-	}
-	if (tbl)
-	{
-		free(tbl);
-		tbl = NULL;
-	}
-	DLFreeElem(tbl_to_remove);
-}
-
-/* Free the entire table list */
-static void
-free_tbl_list(Dllist *tbl_list)
-{
-	Dlelem	   *tbl_elem = DLGetHead(tbl_list);
-	Dlelem	   *tbl_elem_to_remove = NULL;
-
-	while (tbl_elem != NULL)
-	{
-		tbl_elem_to_remove = tbl_elem;
-		tbl_elem = DLGetSucc(tbl_elem);
-		remove_table_from_list(tbl_elem_to_remove);
-	}
-	DLFreeList(tbl_list);
-}
-
-static void
-print_table_list(Dllist *table_list)
-{
-	Dlelem	   *table_elem = DLGetHead(table_list);
-
-	while (table_elem != NULL)
-	{
-		print_table_info(((tbl_info *) DLE_VAL(table_elem)));
-		table_elem = DLGetSucc(table_elem);
-	}
-}
-
-static void
-print_table_info(tbl_info * tbl)
-{
-	sprintf(logbuffer, "  table name: %s.%s", tbl->dbi->dbname, tbl->table_name);
-	log_entry(logbuffer, LVL_INFO);
-	sprintf(logbuffer, "     relid: %u;   relisshared: %d", tbl->relid, tbl->relisshared);
-	log_entry(logbuffer, LVL_INFO);
-	sprintf(logbuffer, "     reltuples: %f;  relpages: %u", tbl->reltuples, tbl->relpages);
-	log_entry(logbuffer, LVL_INFO);
-	sprintf(logbuffer, "     curr_analyze_count: %li; curr_vacuum_count: %li",
-			tbl->curr_analyze_count, tbl->curr_vacuum_count);
-	log_entry(logbuffer, LVL_INFO);
-	sprintf(logbuffer, "     last_analyze_count: %li; last_vacuum_count: %li",
-			tbl->CountAtLastAnalyze, tbl->CountAtLastVacuum);
-	log_entry(logbuffer, LVL_INFO);
-	sprintf(logbuffer, "     analyze_threshold: %li; vacuum_threshold: %li",
-			tbl->analyze_threshold, tbl->vacuum_threshold);
-	log_entry(logbuffer, LVL_INFO);
-	fflush(LOGOUTPUT);
-}
-
-/* End of table Management Functions */
-
-/* Beginning of DB Management Functions */
-
-/* init_db_list() creates the db_list and initalizes template1 */
-static Dllist *
-init_db_list(void)
-{
-	Dllist	   *db_list = DLNewList();
-	db_info    *dbs = NULL;
-	PGresult   *res = NULL;
-#ifdef WIN32
-	int			k = 0;
-#endif
-
-	DLAddHead(db_list, DLNewElem(init_dbinfo((char *) "template1", 0, 0)));
-	if (DLGetHead(db_list) == NULL)
-	{							/* Make sure init_dbinfo was successful */
-		log_entry("init_db_list(): Error creating db_list for db: template1.", LVL_ERROR);
-		fflush(LOGOUTPUT);
-		return NULL;
-	}
-
-	/*
-	 * We do this just so we can set the proper oid for the template1
-	 * database
-	 */
-	dbs = ((db_info *) DLE_VAL(DLGetHead(db_list)));
-	dbs->conn = db_connect(dbs);
-
-#ifdef WIN32
-	while (dbs->conn == NULL && !appMode && k < 10)
-	{
-		int        j;
-
-		/* Pause for 30 seconds to allow the database to start up */
-		log_entry("Pausing 30 seconds to allow the database to startup completely", LVL_INFO);
-		fflush(LOGOUTPUT);
-		ServiceStatus.dwWaitHint = 10;
-		for (j=0; j<6; j++)
-		{
-			pg_usleep(5000000);
-			ServiceStatus.dwCheckPoint++;
-			SetServiceStatus(hStatus, &ServiceStatus);
-			fflush(LOGOUTPUT);
-		}
-
-		/* now try again */
-		log_entry("Attempting to connect again.", LVL_INFO);
-		dbs->conn = db_connect(dbs);
-		k++;
-	}
-#endif
-
-	if (dbs->conn != NULL)
-	{
-		res = send_query(FROZENOID_QUERY, dbs);
-		if (res != NULL)
-		{
-			dbs->oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "oid")));
-			dbs->age = atol(PQgetvalue(res, 0, PQfnumber(res, "age")));
-			if (res)
-				PQclear(res);
-
-			if (args->debug >= 2)
-				print_db_list(db_list, 0);
-		}
-		else
-			return NULL;
-	}
-	return db_list;
-}
-
-/* Simple function to create an instance of the dbinfo struct
-	Initalizes all the pointers and connects to the database  */
-static db_info *
-init_dbinfo(char *dbname, Oid oid, long age)
-{
-	db_info    *newdbinfo = (db_info *) malloc(sizeof(db_info));
-
-	newdbinfo->analyze_threshold = args->vacuum_base_threshold;
-	newdbinfo->vacuum_threshold = args->analyze_base_threshold;
-	newdbinfo->dbname = (char *) malloc(strlen(dbname) + 1);
-	strcpy(newdbinfo->dbname, dbname);
-	newdbinfo->username = NULL;
-	if (args->user != NULL)
-	{
-		newdbinfo->username = (char *) malloc(strlen(args->user) + 1);
-		strcpy(newdbinfo->username, args->user);
-	}
-	newdbinfo->password = NULL;
-	if (args->password != NULL)
-	{
-		newdbinfo->password = (char *) malloc(strlen(args->password) + 1);
-		strcpy(newdbinfo->password, args->password);
-	}
-	newdbinfo->oid = oid;
-	newdbinfo->age = age;
-	newdbinfo->table_list = DLNewList();
-	newdbinfo->conn = NULL;
-
-	if (args->debug >= 2)
-		print_table_list(newdbinfo->table_list);
-
-	return newdbinfo;
-}
-
-/* Function adds and removes databases from the db_list as appropriate */
-static void
-update_db_list(Dllist *db_list)
-{
-	int			disconnect = 0;
-	PGresult   *res = NULL;
-	Dlelem	   *db_elem = DLGetHead(db_list);
-	db_info    *dbi = NULL;
-	db_info    *dbi_template1 = DLE_VAL(db_elem);
-	int			i = 0,
-				t = 0,
-				found_match = 0;
-
-	if (args->debug >= 2)
-	{
-		log_entry("updating the database list", LVL_DEBUG);
-		fflush(LOGOUTPUT);
-	}
-
-	if (dbi_template1->conn == NULL)
-	{
-		dbi_template1->conn = db_connect(dbi_template1);
-		disconnect = 1;
-	}
-
-	if (dbi_template1->conn != NULL)
-	{
-		/*
-		 * Get a result set that has all the information we will need to
-		 * both remove databasews from the list that no longer exist and
-		 * add databases to the list that are new
-		 */
-		res = send_query(FROZENOID_QUERY2, dbi_template1);
-		if (res != NULL)
-		{
-			t = PQntuples(res);
-
-			/*
-			 * First: use the db_list as the outer loop and the result set
-			 * as the inner loop, this will determine what databases
-			 * should be removed
-			 */
-			while (db_elem != NULL)
-			{
-				dbi = ((db_info *) DLE_VAL(db_elem));
-				found_match = 0;
-
-				for (i = 0; i < t; i++)
-				{				/* loop through result set looking for a
-								 * match */
-					if (dbi->oid == atooid(PQgetvalue(res, i, PQfnumber(res, "oid"))))
-					{
-						found_match = 1;
-
-						/*
-						 * update the dbi->age so that we ensure
-						 * xid_wraparound won't happen
-						 */
-						dbi->age = atol(PQgetvalue(res, i, PQfnumber(res, "age")));
-						break;
-					}
-				}
-				if (found_match == 0)
-				{				/* then we didn't find this db_elem in the
-								 * result set */
-					Dlelem	   *elem_to_remove = db_elem;
-
-					db_elem = DLGetSucc(db_elem);
-					remove_db_from_list(elem_to_remove);
-				}
-				else
-					db_elem = DLGetSucc(db_elem);
-			}					/* Done removing dropped databases from
-								 * the table_list */
-
-			/*
-			 * Then loop use result set as outer loop and db_list as the
-			 * inner loop to determine what databases are new
-			 */
-			for (i = 0; i < t; i++)
-			{
-				db_elem = DLGetHead(db_list);
-				found_match = 0;
-				while (db_elem != NULL)
-				{
-					dbi = ((db_info *) DLE_VAL(db_elem));
-					if (dbi->oid == atooid(PQgetvalue(res, i, PQfnumber(res, "oid"))))
-					{
-						found_match = 1;
-						break;
-					}
-					db_elem = DLGetSucc(db_elem);
-				}
-				if (found_match == 0)	/* then we didn't find this result
-										 * now in the tbl_list */
-				{
-					DLAddTail(db_list, DLNewElem(init_dbinfo
-						  (PQgetvalue(res, i, PQfnumber(res, "datname")),
-					   atooid(PQgetvalue(res, i, PQfnumber(res, "oid"))),
-					  atol(PQgetvalue(res, i, PQfnumber(res, "age"))))));
-					if (args->debug >= 1)
-					{
-						sprintf(logbuffer, "added database: %s", ((db_info *) DLE_VAL(DLGetTail(db_list)))->dbname);
-						log_entry(logbuffer, LVL_DEBUG);
-					}
-				}
-			}					/* end of for loop that adds tables */
-		}
-		fflush(LOGOUTPUT);
-		PQclear(res);
-		res = NULL;
-		if (args->debug >= 3)
-			print_db_list(db_list, 0);
-		if (disconnect)
-			db_disconnect(dbi_template1);
-	}
-}
-
-/* xid_wraparound_check
-
-From the docs:
-
-With the standard freezing policy, the age column will start at one billion for a
-freshly-vacuumed database. When the age approaches two billion, the database must
-be vacuumed again to avoid risk of wraparound failures. Recommended practice is
-to vacuum each database at least once every half-a-billion (500 million) transactions,
-so as to provide plenty of safety margin.
-
-So we do a full database vacuum if age > 1.5billion
-return 0 if nothing happened,
-return 1 if the database needed a database wide vacuum
-*/
-static int
-xid_wraparound_check(db_info * dbi)
-{
-	/*
-	 * FIXME: should probably do something better here so that we don't
-	 * vacuum all the databases on the server at the same time.  We have
-	 * 500million xacts to work with so we should be able to spread the
-	 * load of full database vacuums a bit
-	 */
-	if (dbi->age > 1500000000)
-	{
-		PGresult   *res = NULL;
-
-		res = send_query("VACUUM", dbi);
-		/* FIXME: Perhaps should add a check for PQ_COMMAND_OK */
-		if (res != NULL)
-			PQclear(res);
-		return 1;
-	}
-	return 0;
-}
-
-/* Close DB connection, free memory, and remove the node from the list */
-static void
-remove_db_from_list(Dlelem *db_to_remove)
-{
-	db_info    *dbi = ((db_info *) DLE_VAL(db_to_remove));
-
-	if (args->debug >= 1)
-	{
-		sprintf(logbuffer, "Removing db: %s from list.", dbi->dbname);
-		log_entry(logbuffer, LVL_DEBUG);
-		fflush(LOGOUTPUT);
-	}
-	DLRemove(db_to_remove);
-	if (dbi->conn)
-		db_disconnect(dbi);
-	if (dbi->dbname)
-	{
-		free(dbi->dbname);
-		dbi->dbname = NULL;
-	}
-	if (dbi->username)
-	{
-		free(dbi->username);
-		dbi->username = NULL;
-	}
-	if (dbi->password)
-	{
-		free(dbi->password);
-		dbi->password = NULL;
-	}
-	if (dbi->table_list)
-	{
-		free_tbl_list(dbi->table_list);
-		dbi->table_list = NULL;
-	}
-	if (dbi)
-	{
-		free(dbi);
-		dbi = NULL;
-	}
-	DLFreeElem(db_to_remove);
-}
-
-/* Function is called before program exit to free all memory
-		mostly it's just to keep valgrind happy */
-static void
-free_db_list(Dllist *db_list)
-{
-	Dlelem	   *db_elem = DLGetHead(db_list);
-	Dlelem	   *db_elem_to_remove = NULL;
-
-	while (db_elem != NULL)
-	{
-		db_elem_to_remove = db_elem;
-		db_elem = DLGetSucc(db_elem);
-		remove_db_from_list(db_elem_to_remove);
-		db_elem_to_remove = NULL;
-	}
-	DLFreeList(db_list);
-}
-
-static void
-print_db_list(Dllist *db_list, int print_table_lists)
-{
-	Dlelem	   *db_elem = DLGetHead(db_list);
-
-	while (db_elem != NULL)
-	{
-		print_db_info(((db_info *) DLE_VAL(db_elem)), print_table_lists);
-		db_elem = DLGetSucc(db_elem);
-	}
-}
-
-static void
-print_db_info(db_info * dbi, int print_tbl_list)
-{
-	sprintf(logbuffer, "dbname: %s", (dbi->dbname) ? dbi->dbname : "(null)");
-	log_entry(logbuffer, LVL_INFO);
-
-	sprintf(logbuffer, "  oid: %u", dbi->oid);
-	log_entry(logbuffer, LVL_INFO);
-
-	sprintf(logbuffer, "  username: %s", (dbi->username) ? dbi->username : "(null)");
-	log_entry(logbuffer, LVL_INFO);
-
-	sprintf(logbuffer, "  password: %s", (dbi->password) ? dbi->password : "(null)");
-	log_entry(logbuffer, LVL_INFO);
-
-	if (dbi->conn != NULL)
-		log_entry("  conn is valid, (connected)", LVL_INFO);
-	else
-		log_entry("  conn is null, (not connected)", LVL_INFO);
-
-	sprintf(logbuffer, "  default_analyze_threshold: %li", dbi->analyze_threshold);
-	log_entry(logbuffer, LVL_INFO);
-
-	sprintf(logbuffer, "  default_vacuum_threshold: %li", dbi->vacuum_threshold);
-	log_entry(logbuffer, LVL_INFO);
-
-	fflush(LOGOUTPUT);
-	if (print_tbl_list > 0)
-		print_table_list(dbi->table_list);
-}
-
-/* End of DB List Management Function */
-
-/* Beginning of misc Functions */
-
-/* Perhaps add some test to this function to make sure that the stats we need are available */
-static PGconn *
-db_connect(db_info * dbi)
-{
-	PGconn	   *db_conn =
-	PQsetdbLogin(args->host, args->port, NULL, NULL, dbi->dbname,
-				 dbi->username, dbi->password);
-
-	if (PQstatus(db_conn) != CONNECTION_OK)
-	{
-		sprintf(logbuffer, "Failed connection to database %s with error: %s.",
-				dbi->dbname, PQerrorMessage(db_conn));
-		log_entry(logbuffer, LVL_ERROR);
-		fflush(LOGOUTPUT);
-		PQfinish(db_conn);
-		db_conn = NULL;
-	}
-
-	return db_conn;
-}	/* end of db_connect() */
-
-static void
-db_disconnect(db_info * dbi)
-{
-	if (dbi->conn != NULL)
-	{
-		PQfinish(dbi->conn);
-		dbi->conn = NULL;
-	}
-}
-
-static int
-check_stats_enabled(db_info * dbi)
-{
-	PGresult   *res;
-	int			ret = 0;
-
-	res = send_query("SHOW stats_row_level", dbi);
-	if (res != NULL)
-	{
-		ret = strcmp("on", PQgetvalue(res, 0, PQfnumber(res, "stats_row_level")));
-		PQclear(res);
-	}
-	return ret;
-}
-
-static PGresult *
-send_query(const char *query, db_info * dbi)
-{
-	PGresult   *res;
-
-	if (dbi->conn == NULL)
-		return NULL;
-
-	if (args->debug >= 4)
-		log_entry(query, LVL_DEBUG);
-
-	res = PQexec(dbi->conn, query);
-
-	if (!res)
-	{
-		sprintf(logbuffer,
-		   "Fatal error occured while sending query (%s) to database %s",
-				query, dbi->dbname);
-		log_entry(logbuffer, LVL_ERROR);
-		sprintf(logbuffer, "The error is [%s]", PQresultErrorMessage(res));
-		log_entry(logbuffer, LVL_EXTRA);
-		fflush(LOGOUTPUT);
-		return NULL;
-	}
-	if (PQresultStatus(res) != PGRES_TUPLES_OK &&
-		PQresultStatus(res) != PGRES_COMMAND_OK)
-	{
-		sprintf(logbuffer,
-		  "Can not refresh statistics information from the database %s.",
-				dbi->dbname);
-		log_entry(logbuffer, LVL_ERROR);
-		sprintf(logbuffer, "The error is [%s]", PQresultErrorMessage(res));
-		log_entry(logbuffer, LVL_EXTRA);
-		fflush(LOGOUTPUT);
-		PQclear(res);
-		return NULL;
-	}
-	return res;
-}	/* End of send_query() */
-
-/*
- * Perform either a vacuum or a vacuum analyze
- */
-static void
-perform_maintenance_command(db_info * dbi, tbl_info * tbl, int operation)
-{
-	char		buf[256];
-
-	/*
-	 * Set the vacuum_cost variables if supplied on command line
-	 */
-	if (args->av_vacuum_cost_delay != -1)
-	{
-		snprintf(buf, sizeof(buf), "set vacuum_cost_delay = %d",
-				 args->av_vacuum_cost_delay);
-		send_query(buf, dbi);
-	}
-	if (args->av_vacuum_cost_page_hit != -1)
-	{
-		snprintf(buf, sizeof(buf), "set vacuum_cost_page_hit = %d",
-				 args->av_vacuum_cost_page_hit);
-		send_query(buf, dbi);
-	}
-	if (args->av_vacuum_cost_page_miss != -1)
-	{
-		snprintf(buf, sizeof(buf), "set vacuum_cost_page_miss = %d",
-				 args->av_vacuum_cost_page_miss);
-		send_query(buf, dbi);
-	}
-	if (args->av_vacuum_cost_page_dirty != -1)
-	{
-		snprintf(buf, sizeof(buf), "set vacuum_cost_page_dirty = %d",
-				 args->av_vacuum_cost_page_dirty);
-		send_query(buf, dbi);
-	}
-	if (args->av_vacuum_cost_limit != -1)
-	{
-		snprintf(buf, sizeof(buf), "set vacuum_cost_limit = %d",
-				 args->av_vacuum_cost_limit);
-		send_query(buf, dbi);
-	}
-
-	/*
-	 * if ((relisshared = t and database != template1) or
-	 * if operation = ANALYZE_ONLY)
-	 * then only do an analyze
-	 */
-	if ((tbl->relisshared > 0 && strcmp("template1", dbi->dbname) != 0) ||
-		(operation == ANALYZE_ONLY))
-		snprintf(buf, sizeof(buf), "ANALYZE %s.%s", dbi->dbname, tbl->table_name);
-	else if (operation == VACUUM_ANALYZE)
-		snprintf(buf, sizeof(buf), "VACUUM ANALYZE %s.%s", dbi->dbname, tbl->table_name);
-	else
-		return;
-
-	if (args->debug >= 1)
-	{
-		sprintf(logbuffer, "Performing: %s on database %s", buf, dbi->dbname);
-		log_entry(logbuffer, LVL_DEBUG);
-		fflush(LOGOUTPUT);
-	}
-
-	send_query(buf, dbi);
-
-	update_table_thresholds(dbi, tbl, operation);
-
-	if (args->debug >= 2)
-		print_table_info(tbl);
-}
-
-static void
-free_cmd_args(void)
-{
-	if (args != NULL)
-	{
-		if (args->user != NULL)
-			free(args->user);
-		if (args->password != NULL)
-			free(args->password);
-		free(args);
-	}
-}
-
-static cmd_args *
-get_cmd_args(int argc, char *argv[])
-{
-	int			c;
-
-	args = (cmd_args *) malloc(sizeof(cmd_args));
-	args->sleep_base_value = SLEEPBASEVALUE;
-	args->sleep_scaling_factor = SLEEPSCALINGFACTOR;
-	args->vacuum_base_threshold = VACBASETHRESHOLD;
-	args->vacuum_scaling_factor = VACSCALINGFACTOR;
-	args->analyze_base_threshold = -1;
-	args->analyze_scaling_factor = -1;
-	args->debug = AUTOVACUUM_DEBUG;
-	args->update_interval = UPDATE_INTERVAL;
-#ifndef WIN32
-	args->daemonize = 0;
-#else
-    args->service_dependencies = 0;
-	args->install_as_service = 0;
-	args->remove_as_service = 0;
-	args->service_user = 0;
-	args->service_password = 0;
-#endif
-	args->user = 0;
-	args->password = 0;
-	args->host = 0;
-	args->logfile = 0;
-	args->port = 0;
-
-	/*
-	 * Cost-Based Vacuum Delay Settings for pg_autovacuum
-	 */
-	args->av_vacuum_cost_delay = -1;
-	args->av_vacuum_cost_page_hit = -1;
-	args->av_vacuum_cost_page_miss = -1;
-	args->av_vacuum_cost_page_dirty = -1;
-	args->av_vacuum_cost_limit = -1;
-
-	/*
-	 * Fixme: Should add some sanity checking such as positive integer
-	 * values etc
-	 */
-#ifndef WIN32
-	while ((c = getopt(argc, argv, "s:S:v:V:a:A:d:U:P:H:L:p:hDc:C:m:n:l:")) != -1)
-#else
-	while ((c = getopt(argc, argv, "s:S:v:V:a:A:d:U:P:H:L:p:hIRN:W:E:c:C:m:n:l:")) != -1)
-#endif
-	{
-		switch (c)
-		{
-			case 's':
-				args->sleep_base_value = atoi(optarg);
-				break;
-			case 'S':
-				args->sleep_scaling_factor = atof(optarg);
-				break;
-			case 'v':
-				args->vacuum_base_threshold = atoi(optarg);
-				break;
-			case 'V':
-				args->vacuum_scaling_factor = atof(optarg);
-				break;
-			case 'a':
-				args->analyze_base_threshold = atoi(optarg);
-				break;
-			case 'A':
-				args->analyze_scaling_factor = atof(optarg);
-				break;
-			case 'i':
-				args->update_interval = atoi(optarg);
-				break;
-			case 'c':
-				args->av_vacuum_cost_delay = atoi(optarg);
-				break;
-			case 'C':
-				args->av_vacuum_cost_page_hit = atoi(optarg);
-				break;
-			case 'm':
-				args->av_vacuum_cost_page_miss = atoi(optarg);
-				break;
-			case 'n':
-				args->av_vacuum_cost_page_dirty = atoi(optarg);
-				break;
-			case 'l':
-				args->av_vacuum_cost_limit = atoi(optarg);
-				break;
-#ifndef WIN32
-			case 'D':
-				args->daemonize++;
-				break;
-#endif
-			case 'd':
-				args->debug = atoi(optarg);
-				break;
-			case 'U':
-				args->user = optarg;
-				break;
-			case 'P':
-				args->password = optarg;
-				break;
-			case 'H':
-				args->host = optarg;
-				break;
-			case 'L':
-				args->logfile = optarg;
-				break;
-			case 'p':
-				args->port = optarg;
-				break;
-			case 'h':
-				usage();
-				exit(0);
-#ifdef WIN32
-			case 'E':
-				/*
-				 * CreateService() expects a list of service
-				 * dependencies as a NUL-separated, double-NUL
-				 * terminated list (although we only allow the user to
-				 * specify a single dependency). So we zero out the
-				 * list first, and make sure to leave room for two NUL
-				 * terminators.
-				 */
-				ZeroMemory(deps, sizeof(deps));
-				snprintf(deps, sizeof(deps) - 2, "%s", optarg);
-				args->service_dependencies = deps;
-				break;
-			case 'I':
-				args->install_as_service++;
-				break;
-			case 'R':
-				args->remove_as_service++;
-				break;
-			case 'N':
-				args->service_user = optarg;
-				break;
-			case 'W':
-				args->service_password = optarg;
-				break;
-#endif
-			default:
-
-				/*
-				 * It's here that we know that things are invalid... It is
-				 * not forcibly an error to call usage
-				 */
-				fprintf(stderr, "Error: Invalid Command Line Options.\n");
-				usage();
-				exit(1);
-				break;
-		}
-
-		/*
-		 * if values for insert thresholds are not specified, then they
-		 * default to 1/2 of the delete values
-		 */
-		if (args->analyze_base_threshold == -1)
-			args->analyze_base_threshold = args->vacuum_base_threshold / 2;
-		if (args->analyze_scaling_factor == -1)
-			args->analyze_scaling_factor = args->vacuum_scaling_factor / 2;
-	}
-	return args;
-}
-
-static void
-usage(void)
-{
-	int			i = 0;
-	float		f = 0;
-
-	fprintf(stderr, "usage: pg_autovacuum \n");
-#ifndef WIN32
-	fprintf(stderr, "   [-D] Daemonize (Detach from tty and run in the background)\n");
-#else
-	fprintf(stderr, "   [-I] Install as a Windows service\n");
-	fprintf(stderr, "   [-R] Remove as a Windows service (all other options will be ignored)\n");
-	fprintf(stderr, "   [-N] Username to run service as (only useful when installing as a Windows service)\n");
-	fprintf(stderr, "   [-W] Password to run service with (only useful when installing as a Windows service)\n");
-	fprintf(stderr, "   [-E] Dependent service that must start before this service (only useful when installing as a Windows service)\n");
-#endif
-	i = AUTOVACUUM_DEBUG;
-	fprintf(stderr, "   [-d] debug (debug level=0,1,2,3; default=%d)\n", i);
-
-	i = SLEEPBASEVALUE;
-	fprintf(stderr, "   [-s] sleep base value (default=%d)\n", i);
-	f = SLEEPSCALINGFACTOR;
-	fprintf(stderr, "   [-S] sleep scaling factor (default=%f)\n", f);
-
-	i = VACBASETHRESHOLD;
-	fprintf(stderr, "   [-v] vacuum base threshold (default=%d)\n", i);
-	f = VACSCALINGFACTOR;
-	fprintf(stderr, "   [-V] vacuum scaling factor (default=%f)\n", f);
-	i = i / 2;
-	fprintf(stderr, "   [-a] analyze base threshold (default=%d)\n", i);
-	f = f / 2;
-	fprintf(stderr, "   [-A] analyze scaling factor (default=%f)\n", f);
-
-	fprintf(stderr, "   [-L] logfile (default=none)\n");
-
-	fprintf(stderr, "   [-c] vacuum_cost_delay (default=none)\n");
-	fprintf(stderr, "   [-C] vacuum_cost_page_hit (default=none)\n");
-	fprintf(stderr, "   [-m] vacuum_cost_page_miss (default=none)\n");
-	fprintf(stderr, "   [-n] vacuum_cost_page_dirty (default=none)\n");
-	fprintf(stderr, "   [-l] vacuum_cost_limit (default=none)\n");
-
-	fprintf(stderr, "   [-U] username (libpq default)\n");
-	fprintf(stderr, "   [-P] password (libpq default)\n");
-	fprintf(stderr, "   [-H] host (libpq default)\n");
-	fprintf(stderr, "   [-p] port (libpq default)\n");
-
-	fprintf(stderr, "   [-h] help (Show this output)\n");
-}
-
-static void
-print_cmd_args(void)
-{
-	sprintf(logbuffer, "Printing command_args");
-	log_entry(logbuffer, LVL_INFO);
-	sprintf(logbuffer, "  args->host=%s", (args->host) ? args->host : "(null)");
-	log_entry(logbuffer, LVL_INFO);
-	sprintf(logbuffer, "  args->port=%s", (args->port) ? args->port : "(null)");
-	log_entry(logbuffer, LVL_INFO);
-	sprintf(logbuffer, "  args->username=%s", (args->user) ? args->user : "(null)");
-	log_entry(logbuffer, LVL_INFO);
-	sprintf(logbuffer, "  args->password=%s", (args->password) ? args->password : "(null)");
-	log_entry(logbuffer, LVL_INFO);
-	sprintf(logbuffer, "  args->logfile=%s", (args->logfile) ? args->logfile : "(null)");
-	log_entry(logbuffer, LVL_INFO);
-#ifndef WIN32
-	sprintf(logbuffer, "  args->daemonize=%d", args->daemonize);
-	log_entry(logbuffer, LVL_INFO);
-#else
-	sprintf(logbuffer, "  args->install_as_service=%d", args->install_as_service);
-	log_entry(logbuffer, LVL_INFO);
-	sprintf(logbuffer, "  args->remove_as_service=%d", args->remove_as_service);
-	log_entry(logbuffer, LVL_INFO);
-	sprintf(logbuffer, "  args->service_dependencies=%s", (args->service_dependencies) ? args->service_dependencies : "(null)");
-	log_entry(logbuffer, LVL_INFO);
-	sprintf(logbuffer, "  args->service_user=%s", (args->service_user) ? args->service_user : "(null)");
-	log_entry(logbuffer, LVL_INFO);
-	sprintf(logbuffer, "  args->service_password=%s", (args->service_password) ? args->service_password : "(null)");
-	log_entry(logbuffer, LVL_INFO);
-#endif
-
-	sprintf(logbuffer, "  args->sleep_base_value=%d", args->sleep_base_value);
-	log_entry(logbuffer, LVL_INFO);
-	sprintf(logbuffer, "  args->sleep_scaling_factor=%f", args->sleep_scaling_factor);
-	log_entry(logbuffer, LVL_INFO);
-	sprintf(logbuffer, "  args->vacuum_base_threshold=%d", args->vacuum_base_threshold);
-	log_entry(logbuffer, LVL_INFO);
-	sprintf(logbuffer, "  args->vacuum_scaling_factor=%f", args->vacuum_scaling_factor);
-	log_entry(logbuffer, LVL_INFO);
-	sprintf(logbuffer, "  args->analyze_base_threshold=%d", args->analyze_base_threshold);
-	log_entry(logbuffer, LVL_INFO);
-	sprintf(logbuffer, "  args->analyze_scaling_factor=%f", args->analyze_scaling_factor);
-	log_entry(logbuffer, LVL_INFO);
-	sprintf(logbuffer, "  args->update_interval=%i", args->update_interval);
-	log_entry(logbuffer, LVL_INFO);
-
-	if (args->av_vacuum_cost_delay != -1)
-		sprintf(logbuffer, "  args->av_vacuum_cost_delay=%d", args->av_vacuum_cost_delay);
-	else
-		sprintf(logbuffer, "  args->av_vacuum_cost_delay=(default)");
-	log_entry(logbuffer, LVL_INFO);
-	if (args->av_vacuum_cost_page_hit != -1)
-		sprintf(logbuffer, "  args->av_vacuum_cost_page_hit=%d", args->av_vacuum_cost_page_hit);
-	else
-		sprintf(logbuffer, "  args->av_vacuum_cost_page_hit=(default)");
-	log_entry(logbuffer, LVL_INFO);
-	if (args->av_vacuum_cost_page_miss != -1)
-		sprintf(logbuffer, "  args->av_vacuum_cost_page_miss=%d", args->av_vacuum_cost_page_miss);
-	else
-		sprintf(logbuffer, "  args->av_vacuum_cost_page_miss=(default)");
-	log_entry(logbuffer, LVL_INFO);
-	if (args->av_vacuum_cost_page_dirty != -1)
-		sprintf(logbuffer, "  args->av_vacuum_cost_page_dirty=%d", args->av_vacuum_cost_page_dirty);
-	else
-		sprintf(logbuffer, "  args->av_vacuum_cost_page_dirty=(default)");
-	log_entry(logbuffer, LVL_INFO);
-	if (args->av_vacuum_cost_limit != -1)
-		sprintf(logbuffer, "  args->av_vacuum_cost_limit=%d", args->av_vacuum_cost_limit);
-	else
-		sprintf(logbuffer, "  args->av_vacuum_cost_limit=(default)");
-	log_entry(logbuffer, LVL_INFO);
-
-	sprintf(logbuffer, "  args->debug=%d", args->debug);
-	log_entry(logbuffer, LVL_INFO);
-
-	fflush(LOGOUTPUT);
-}
-
-#ifdef WIN32
-
-/* Handle control requests from the Service Control Manager */
-static void
-ControlHandler(DWORD request)
-{
-	switch (request)
-	{
-		case SERVICE_CONTROL_STOP:
-		case SERVICE_CONTROL_SHUTDOWN:
-			log_entry("pg_autovacuum service stopping...", LVL_INFO);
-			fflush(LOGOUTPUT);
-			ServiceStatus.dwWin32ExitCode = 0;
-			ServiceStatus.dwCurrentState = SERVICE_STOPPED;
-			SetServiceStatus(hStatus, &ServiceStatus);
-			return;
-
-		default:
-			break;
-	}
-
-	/* Report current status */
-	SetServiceStatus(hStatus, &ServiceStatus);
-
-	return;
-}
-
-/* Register with the Service Control Manager */
-static int
-InstallService(void)
-{
-	SC_HANDLE	schService = NULL;
-	SC_HANDLE	schSCManager = NULL;
-	char		szFilename[MAX_PATH],
-				szKey[MAX_PATH],
-				szCommand[MAX_PATH + 1024],
-				szMsgDLL[MAX_PATH];
-	HKEY		hk = NULL;
-	DWORD		dwData = 0;
-
-	/*
-	 * Register the service with the SCM
-	 */
-	GetModuleFileName(NULL, szFilename, MAX_PATH);
-
-	/* Open the Service Control Manager on the local computer. */
-	schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
-	if (!schSCManager)
-		return -1;
-
-	schService = CreateService(
-							   schSCManager,	/* SCManager database */
-							   TEXT("pg_autovacuum"),	/* Name of service */
-							   TEXT("PostgreSQL Auto Vacuum"),	/* Name to display */
-							   SERVICE_ALL_ACCESS,		/* Desired access */
-							   SERVICE_WIN32_OWN_PROCESS,		/* Service type */
-							   SERVICE_AUTO_START,		/* Start type */
-							   SERVICE_ERROR_NORMAL,	/* Error control type */
-							   szFilename,		/* Service binary */
-							   NULL,	/* No load ordering group */
-							   NULL,	/* No tag identifier */
-							   args->service_dependencies,	/* Dependencies */
-							   args->service_user,		/* Service account */
-							   args->service_password); /* Account password */
-
-	if (!schService)
-		return -2;
-
-	/*
-	 * Rewrite the command line for the service
-	 */
-	sprintf(szKey, "SYSTEM\\CurrentControlSet\\Services\\pg_autovacuum");
-	if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKey, 0, KEY_ALL_ACCESS, &hk))
-		return -3;
-
-	/* Build the command line */
-	sprintf(szCommand, "\"%s\"", szFilename);
-	if (args->host)
-		sprintf(szCommand, "%s -H %s", szCommand, args->host);
-	if (args->port)
-		sprintf(szCommand, "%s -p %s", szCommand, args->port);
-	if (args->user)
-		sprintf(szCommand, "%s -U \"%s\"", szCommand, args->user);
-	if (args->password)
-		sprintf(szCommand, "%s -P \"%s\"", szCommand, args->password);
-	if (args->logfile)
-		sprintf(szCommand, "%s -L \"%s\"", szCommand, args->logfile);
-	if (args->sleep_base_value != (int) SLEEPBASEVALUE)
-		sprintf(szCommand, "%s -s %d", szCommand, args->sleep_base_value);
-	if (args->sleep_scaling_factor != (float) SLEEPSCALINGFACTOR)
-		sprintf(szCommand, "%s -S %f", szCommand, args->sleep_scaling_factor);
-	if (args->vacuum_base_threshold != (int) VACBASETHRESHOLD)
-		sprintf(szCommand, "%s -v %d", szCommand, args->vacuum_base_threshold);
-	if (args->vacuum_scaling_factor != (float) VACSCALINGFACTOR)
-		sprintf(szCommand, "%s -V %f", szCommand, args->vacuum_scaling_factor);
-	if (args->analyze_base_threshold != (int) (VACBASETHRESHOLD / 2))
-		sprintf(szCommand, "%s -a %d", szCommand, args->analyze_base_threshold);
-	if (args->analyze_scaling_factor != (float) (VACSCALINGFACTOR / 2))
-		sprintf(szCommand, "%s -A %f", szCommand, args->analyze_scaling_factor);
-	if (args->debug != (int) AUTOVACUUM_DEBUG)
-		sprintf(szCommand, "%s -d %d", szCommand, args->debug);
-	if (args->av_vacuum_cost_delay != -1)
-		sprintf(szCommand, "%s -d %d", szCommand, args->av_vacuum_cost_delay);
-	if (args->av_vacuum_cost_page_hit != -1)
-		sprintf(szCommand, "%s -d %d", szCommand, args->av_vacuum_cost_page_hit);
-	if (args->av_vacuum_cost_page_miss != -1)
-		sprintf(szCommand, "%s -d %d", szCommand, args->av_vacuum_cost_page_miss);
-	if (args->av_vacuum_cost_page_dirty != -1)
-		sprintf(szCommand, "%s -d %d", szCommand, args->av_vacuum_cost_page_dirty);
-	if (args->av_vacuum_cost_limit != -1)
-		sprintf(szCommand, "%s -d %d", szCommand, args->av_vacuum_cost_limit);
-
-	/* And write the new value */
-	if (RegSetValueEx(hk, "ImagePath", 0, REG_EXPAND_SZ, (LPBYTE) szCommand, (DWORD) strlen(szCommand) + 1))
-		return -4;
-	RegCloseKey(hk);
-
-	/*
-	 * Set the Event source for the application log
-	 */
-	sprintf(szKey, "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\PostgreSQL Auto Vacuum");
-	if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, szKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hk, NULL))
-		return -5;
-
-	/* TODO Try to find pgevent.dll, rather than hope it's in the path. ! */
-	/* Message DLL */
-	sprintf(szMsgDLL, "pgevent.dll");
-	if (RegSetValueEx(hk, "EventMessageFile", 0, REG_EXPAND_SZ, (LPBYTE) szMsgDLL, (DWORD) strlen(szMsgDLL) + 1))
-		return -6;
-
-	/* Set the event types supported */
-	dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE | EVENTLOG_SUCCESS;
-	if (RegSetValueEx(hk, "TypesSupported", 0, REG_DWORD, (LPBYTE) & dwData, sizeof(DWORD)))
-		return -9;
-
-	RegCloseKey(hk);
-	return 0;
-}
-
-/* Unregister from the Service Control Manager */
-static int
-RemoveService(void)
-{
-	SC_HANDLE	schService = NULL;
-	SC_HANDLE	schSCManager = NULL;
-	char		szKey[MAX_PATH];
-	HKEY		hk = NULL;
-
-	/* Open the SCM */
-	schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
-	if (!schSCManager)
-		return -1;
-
-	/* Open the service */
-	schService = OpenService(schSCManager, TEXT("pg_autovacuum"), SC_MANAGER_ALL_ACCESS);
-	if (!schService)
-		return -2;
-
-	/* Now delete the service */
-	if (!DeleteService(schService))
-		return -3;
-
-	/*
-	 * Remove the Event source from the application log
-	 */
-	sprintf(szKey, "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application");
-	if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKey, 0, KEY_ALL_ACCESS, &hk))
-		return -4;
-	if (RegDeleteKey(hk, "PostgreSQL Auto Vacuum"))
-		return -5;
-
-	return 0;
-}
-#endif   /* WIN32 */
-
-static
-int
-VacuumLoop(int argc, char **argv)
-{
-	int			j = 0,
-				loops = 0;
-
-	/* int numInserts, numDeletes, */
-	int			sleep_secs;
-	Dllist	   *db_list;
-	Dlelem	   *db_elem,
-			   *tbl_elem;
-	db_info    *dbs;
-	tbl_info   *tbl;
-	PGresult   *res = NULL;
-	double		diff;
-
-	struct timeval now,
-				then;
-
-#ifdef WIN32
-
-	if (appMode)
-		log_entry("pg_autovacuum starting in Windows Application mode", LVL_INFO);
-	else
-		log_entry("pg_autovacuum starting in Windows Service mode", LVL_INFO);
-
-	ServiceStatus.dwServiceType = SERVICE_WIN32;
-	ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
-	ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
-	ServiceStatus.dwWin32ExitCode = 0;
-	ServiceStatus.dwServiceSpecificExitCode = 0;
-	ServiceStatus.dwCheckPoint = 0;
-	ServiceStatus.dwWaitHint = 0;
-
-	if (!appMode)
-	{
-		hStatus = RegisterServiceCtrlHandler("pg_autovacuum", (LPHANDLER_FUNCTION) ControlHandler);
-		if (hStatus == (SERVICE_STATUS_HANDLE) 0)
-			return -1;
-	}
-#endif   /* WIN32 */
-
-	/* Init the db list with template1 */
-	db_list = init_db_list();
-	if (db_list == NULL)
-		return 1;
-
-	if (check_stats_enabled(((db_info *) DLE_VAL(DLGetHead(db_list)))) != 0)
-	{
-		log_entry("GUC variable stats_row_level must be enabled.", LVL_ERROR);
-		log_entry("       Please fix the problems and try again.", LVL_EXTRA);
-		fflush(LOGOUTPUT);
-
-		exit(1);
-	}
-
-	gettimeofday(&then, 0);		/* for use later to caluculate sleep time */
-
-#ifndef WIN32
-	while (1)
-#else
-	/* We can now report the running status to SCM. */
-	ServiceStatus.dwCurrentState = SERVICE_RUNNING;
-	if (!appMode)
-		SetServiceStatus(hStatus, &ServiceStatus);
-
-	while (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
-#endif
-	{
-		/* Main Loop */
-
-		db_elem = DLGetHead(db_list);	/* Reset cur_db_node to the
-										 * beginning of the db_list */
-
-		dbs = ((db_info *) DLE_VAL(db_elem));	/* get pointer to cur_db's
-												 * db_info struct */
-		if (dbs->conn == NULL)
-		{
-			dbs->conn = db_connect(dbs);
-			if (dbs->conn == NULL)
-			{					/* Serious problem: We can't connect to
-								 * template1 */
-				log_entry("Cannot connect to template1, exiting.", LVL_ERROR);
-				fflush(LOGOUTPUT);
-				fclose(LOGOUTPUT);
-#ifdef WIN32
-				ServiceStatus.dwCurrentState = SERVICE_STOPPED;
-				ServiceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
-				ServiceStatus.dwServiceSpecificExitCode = -1;
-				if (!appMode)
-					SetServiceStatus(hStatus, &ServiceStatus);
-#endif
-				exit(1);
-			}
-		}
-
-		if (loops % args->update_interval == 0)		/* Update the list if it's
-													 * time */
-			update_db_list(db_list);	/* Add and remove databases from
-										 * the list */
-
-		while (db_elem != NULL)
-		{						/* Loop through databases in list */
-			dbs = ((db_info *) DLE_VAL(db_elem));		/* get pointer to
-														 * cur_db's db_info
-														 * struct */
-			if (dbs->conn == NULL)
-				dbs->conn = db_connect(dbs);
-
-			if (dbs->conn != NULL)
-			{
-				if (loops % args->update_interval == 0)		/* Update the list if
-															 * it's time */
-					update_table_list(dbs);		/* Add and remove tables
-												 * from the list */
-
-				if (xid_wraparound_check(dbs) == 0)
-				{
-					res = send_query(TABLE_STATS_QUERY, dbs);	/* Get an updated
-																 * snapshot of this dbs
-																 * table stats */
-					if (res != NULL)
-					{
-						for (j = 0; j < PQntuples(res); j++)
-						{		/* loop through result set */
-							tbl_elem = DLGetHead(dbs->table_list);		/* Reset tbl_elem to top
-																		 * of dbs->table_list */
-							while (tbl_elem != NULL)
-							{	/* Loop through tables in list */
-								tbl = ((tbl_info *) DLE_VAL(tbl_elem)); /* set tbl_info =
-																		 * current_table */
-								if (tbl->relid == atooid(PQgetvalue(res, j, PQfnumber(res, "oid"))))
-								{
-									tbl->curr_analyze_count =
-										(atol(PQgetvalue(res, j, PQfnumber(res, "n_tup_ins"))) +
-										 atol(PQgetvalue(res, j, PQfnumber(res, "n_tup_upd"))) +
-										 atol(PQgetvalue(res, j, PQfnumber(res, "n_tup_del"))));
-									tbl->curr_vacuum_count =
-										(atol(PQgetvalue(res, j, PQfnumber(res, "n_tup_del"))) +
-										 atol(PQgetvalue(res, j, PQfnumber(res, "n_tup_upd"))));
-
-									/*
-									 * Check numDeletes to see if we need
-									 * to vacuum, if so: Run vacuum
-									 * analyze (adding analyze is small so
-									 * we might as well) Update table
-									 * thresholds and related information
-									 * if numDeletes is not big enough for
-									 * vacuum then check numInserts for
-									 * analyze
-									 */
-									if (tbl->curr_vacuum_count - tbl->CountAtLastVacuum >= tbl->vacuum_threshold)
-										perform_maintenance_command(dbs, tbl, VACUUM_ANALYZE);
-									else if (tbl->curr_analyze_count - tbl->CountAtLastAnalyze >= tbl->analyze_threshold)
-										perform_maintenance_command(dbs, tbl, ANALYZE_ONLY);
-
-									break;		/* We found a match, no need to keep looping. */
-								}
-
-								/*
-								 * Advance the table pointers for the next
-								 * loop
-								 */
-								tbl_elem = DLGetSucc(tbl_elem);
-
-							}	/* end for table while loop */
-						}		/* end for j loop (tuples in PGresult) */
-					}			/* end if (res != NULL) */
-				}				/* close of if (xid_wraparound_check()) */
-				/* Done working on this db, Clean up, then advance cur_db */
-				PQclear(res);
-				res = NULL;
-				db_disconnect(dbs);
-			}
-			db_elem = DLGetSucc(db_elem);		/* move on to next DB
-												 * regardless */
-		}						/* end of db_list while loop */
-
-		/* Figure out how long to sleep etc ... */
-		gettimeofday(&now, 0);
-		diff = (int) (now.tv_sec - then.tv_sec) * 1000000.0 + (int) (now.tv_usec - then.tv_usec);
-
-		sleep_secs = args->sleep_base_value + args->sleep_scaling_factor * diff / 1000000.0;
-		loops++;
-		if (args->debug >= 2)
-		{
-			sprintf(logbuffer,
-			 "%d All DBs checked in: %.0f usec, will sleep for %d secs.",
-					loops, diff, sleep_secs);
-			log_entry(logbuffer, LVL_DEBUG);
-			fflush(LOGOUTPUT);
-		}
-
-		/* Larger Pause between outer loops */
-		/*
-		 *	pg_usleep() is wrong here because its maximum is ~2000 seconds,
-		 *	and we don't need signal interruptability on Win32 here.
-		 */
-#ifndef WIN32
-		sleep(sleep_secs);			/* Unix sleep is seconds */
-#else
-		sleep(sleep_secs * 1000);	/* Win32 sleep() is milliseconds */
-#endif
-
-		gettimeofday(&then, 0); /* Reset time counter */
-
-	}							/* end of while loop */
-
-	/*
-	 * program is exiting, this should never run, but is here to make
-	 * compiler / valgrind happy
-	 */
-	free_db_list(db_list);
-	free_cmd_args();
-	return 0;
-}
-
-/* Beginning of AutoVacuum Main Program */
-int
-main(int argc, char *argv[])
-{
-
-#ifdef WIN32
-	LPVOID		lpMsgBuf;
-	SERVICE_TABLE_ENTRY ServiceTable[2];
-#endif
-
-	args = get_cmd_args(argc, argv);	/* Get Command Line Args and put
-										 * them in the args struct */
-#ifndef WIN32
-	/* Dameonize if requested */
-	if (args->daemonize == 1)
-		daemonize();
-#endif
-
-	if (args->logfile)
-	{
-		LOGOUTPUT = fopen(args->logfile, "a");
-		if (!LOGOUTPUT)
-		{
-			fprintf(stderr, "Could not open log file - [%s]\n", args->logfile);
-			exit(-1);
-		}
-	}
-	else
-		LOGOUTPUT = stderr;
-	if (args->debug >= 2)
-		print_cmd_args();
-
-#ifdef WIN32
-	/* Install as a Windows service if required */
-	if (args->install_as_service)
-	{
-		if (InstallService() != 0)
-		{
-			FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) & lpMsgBuf, 0, NULL);
-            fprintf(stderr, "Error: %s\n", (char *) lpMsgBuf);
-			exit(-1);
-		}
-		else
-		{
-			fprintf(stderr, "Successfully installed pg_autovacuum as a service.\n");
-			exit(0);
-		}
-	}
-
-	/* Remove as a Windows service if required */
-	if (args->remove_as_service)
-	{
-		if (RemoveService() != 0)
-		{
-			FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) & lpMsgBuf, 0, NULL);
-            fprintf(stderr, "Error: %s\n", (char *) lpMsgBuf);
-			exit(-1);
-		}
-		else
-		{
-			fprintf(stderr, "Successfully removed pg_autovacuum as a service.\n");
-			exit(0);
-		}
-	}
-
-	/* Normal service startup */
-	ServiceTable[0].lpServiceName = "pg_autovacuum";
-	ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION) VacuumLoop;
-
-	ServiceTable[1].lpServiceName = NULL;
-	ServiceTable[1].lpServiceProc = NULL;
-
-	/* Start the control dispatcher thread for our service */
-	if (!StartServiceCtrlDispatcher(ServiceTable))
-	{
-		appMode = 1;
-		VacuumLoop(0, NULL);
-	}
-
-#else							/* Unix */
-
-	/* Call the main program loop. */
-	VacuumLoop(0, NULL);
-#endif   /* WIN32 */
-
-	return EXIT_SUCCESS;
-}
diff --git a/contrib/pg_autovacuum/pg_autovacuum.h b/contrib/pg_autovacuum/pg_autovacuum.h
deleted file mode 100644
index 5c6186d7fb4c8238a6b27ecf826e192b214bc5aa..0000000000000000000000000000000000000000
--- a/contrib/pg_autovacuum/pg_autovacuum.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/* pg_autovacuum.h
- * Header file for pg_autovacuum.c
- * (c) 2003 Matthew T. O'Connor
- *
- * $PostgreSQL: pgsql/contrib/pg_autovacuum/pg_autovacuum.h,v 1.15 2005/04/19 03:35:15 momjian Exp $
- */
-
-#ifndef _PG_AUTOVACUUM_H
-#define _PG_AUTOVACUUM_H
-
-#include "libpq-fe.h"
-#include "lib/dllist.h"
-
-#define AUTOVACUUM_DEBUG	0
-#define VACBASETHRESHOLD	1000
-#define VACSCALINGFACTOR	2
-#define SLEEPBASEVALUE		300
-#define SLEEPSCALINGFACTOR	2
-#define UPDATE_INTERVAL		2
-
-/* these two constants are used to tell update_table_stats what operation we just perfomred */
-#define VACUUM_ANALYZE		0
-#define ANALYZE_ONLY		1
-
-
-#define TABLE_STATS_QUERY	"select a.oid,a.relname,a.relnamespace,a.relpages,a.relisshared,a.reltuples,b.schemaname,b.n_tup_ins,b.n_tup_upd,b.n_tup_del from pg_class a, pg_stat_all_tables b where a.oid=b.relid and a.relkind = 'r'"
-
-#define PAGES_QUERY "select oid,reltuples,relpages from pg_class where oid=%u"
-#define FROZENOID_QUERY "select oid,age(datfrozenxid) from pg_database where datname = 'template1'"
-#define FROZENOID_QUERY2 "select oid,datname,age(datfrozenxid) from pg_database where datname!='template0'"
-
-/* Log levels */
-enum
-{
-	LVL_DEBUG = 1,
-	LVL_INFO,
-	LVL_WARNING,
-	LVL_ERROR,
-	LVL_EXTRA
-};
-
-/* define cmd_args stucture */
-typedef struct cmdargs
-{
-	int			vacuum_base_threshold,
-				analyze_base_threshold,
-				update_interval,
-				sleep_base_value,
-				debug,
-				
-				/*
-				 * Cost-Based Vacuum Delay Settings for pg_autovacuum
-				 */
-				av_vacuum_cost_delay,
-				av_vacuum_cost_page_hit,
-				av_vacuum_cost_page_miss,
-				av_vacuum_cost_page_dirty,
-				av_vacuum_cost_limit,
-				
-#ifndef WIN32
-				daemonize;
-#else
-				install_as_service,
-				remove_as_service;
-#endif
-	float		vacuum_scaling_factor,
-				analyze_scaling_factor,
-				sleep_scaling_factor;
-	char	   *user,
-			   *password,
-#ifdef WIN32
-			   *service_dependencies,
-			   *service_user,
-			   *service_password,
-#endif
-			   *host,
-			   *logfile,
-			   *port;
-} cmd_args;
-
-/*
- * Might need to add a time value for last time the whole database was
- * vacuumed.  We need to guarantee this happens approx every 1Billion TX's
- */
-typedef struct dbinfo
-{
-	Oid			oid;
-	long		age;
-	long		analyze_threshold,
-				vacuum_threshold;		/* Use these as defaults for table
-										 * thresholds */
-	PGconn	   *conn;
-	char	   *dbname,
-			   *username,
-			   *password;
-	Dllist	   *table_list;
-} db_info;
-
-typedef struct tableinfo
-{
-	char	   *schema_name,
-			   *table_name;
-	float		reltuples;
-	int			relisshared;
-	Oid			relid,
-				relpages;
-	long		analyze_threshold,
-				vacuum_threshold;
-	long		CountAtLastAnalyze;		/* equal to: inserts + updates as
-										 * of the last analyze or initial
-										 * values at startup */
-	long		CountAtLastVacuum;		/* equal to: deletes + updates as
-										 * of the last vacuum or initial
-										 * values at startup */
-	long		curr_analyze_count,
-				curr_vacuum_count;		/* Latest values from stats system */
-	db_info    *dbi;			/* pointer to the database that this table
-								 * belongs to */
-} tbl_info;
-
-#endif /* _PG_AUTOVACUUM_H */