text: /*-------------------------------------------------------------------------
   *
   * vacuum.h
   *	  header file for postgres vacuum cleaner and statistics analyzer
   *
   *
   * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
   * Portions Copyright (c) 1994, Regents of the University of California
   *
   * $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.85 2009/06/11 14:49:11 momjian Exp $
   *
   *-------------------------------------------------------------------------
   */
  #ifndef VACUUM_H
  #define VACUUM_H
  
  #include "access/htup.h"
  #include "catalog/pg_statistic.h"
  #include "catalog/pg_type.h"
  #include "nodes/parsenodes.h"
  #include "storage/buf.h"
  #include "storage/lock.h"
  #include "utils/relcache.h"
  
  
  /*----------
   * ANALYZE builds one of these structs for each attribute (column) that is
   * to be analyzed.	The struct and subsidiary data are in anl_context,
   * so they live until the end of the ANALYZE operation.
   *
   * The type-specific typanalyze function is passed a pointer to this struct
   * and must return TRUE to continue analysis, FALSE to skip analysis of this
   * column.	In the TRUE case it must set the compute_stats and minrows fields,
   * and can optionally set extra_data to pass additional info to compute_stats.
   * minrows is its request for the minimum number of sample rows to be gathered
   * (but note this request might not be honored, eg if there are fewer rows
   * than that in the table).
   *
   * The compute_stats routine will be called after sample rows have been
   * gathered.  Aside from this struct, it is passed:
   *		fetchfunc: a function for accessing the column values from the
   *				   sample rows
   *		samplerows: the number of sample tuples
   *		totalrows: estimated total number of rows in relation
   * The fetchfunc may be called with rownum running from 0 to samplerows-1.
   * It returns a Datum and an isNull flag.
   *
   * compute_stats should set stats_valid TRUE if it is able to compute
   * any useful statistics.  If it does, the remainder of the struct holds
   * the information to be stored in a pg_statistic row for the column.  Be
   * careful to allocate any pointed-to data in anl_context, which will NOT
   * be CurrentMemoryContext when compute_stats is called.
   *----------
   */
  typedef struct VacAttrStats *VacAttrStatsP;
  
  typedef Datum (*AnalyzeAttrFetchFunc) (VacAttrStatsP stats, int rownum,
  												   bool *isNull);
  
  typedef struct VacAttrStats
  {
  	/*
  	 * These fields are set up by the main ANALYZE code before invoking the
  	 * type-specific typanalyze function.
  	 */
  	Form_pg_attribute attr;		/* copy of pg_attribute row for column */
  	Form_pg_type attrtype;		/* copy of pg_type row for column */
  	MemoryContext anl_context;	/* where to save long-lived data */
  
  	/*
  	 * These fields must be filled in by the typanalyze routine, unless it
  	 * returns FALSE.
  	 */
  	void		(*compute_stats) (VacAttrStatsP stats,
  											  AnalyzeAttrFetchFunc fetchfunc,
  											  int samplerows,
  											  double totalrows);
  	int			minrows;		/* Minimum # of rows wanted for stats */
  	void	   *extra_data;		/* for extra type-specific data */
  
  	/*
  	 * These fields are to be filled in by the compute_stats routine. (They
  	 * are initialized to zero when the struct is created.)
  	 */
  	bool		stats_valid;
  	float4		stanullfrac;	/* fraction of entries that are NULL */
  	int4		stawidth;		/* average width of column values */
  	float4		stadistinct;	/* # distinct values */
  	int2		stakind[STATISTIC_NUM_SLOTS];
  	Oid			staop[STATISTIC_NUM_SLOTS];
  	int			numnumbers[STATISTIC_NUM_SLOTS];
  	float4	   *stanumbers[STATISTIC_NUM_SLOTS];
  	int			numvalues[STATISTIC_NUM_SLOTS];
  	Datum	   *stavalues[STATISTIC_NUM_SLOTS];
  
  	/*
  	 * These fields describe the stavalues[n] element types. They will be
  	 * initialized to be the same as the column's that's underlying the slot,
  	 * but a custom typanalyze function might want to store an array of
  	 * something other than the analyzed column's elements. It should then
  	 * overwrite these fields.
  	 */
  	Oid			statypid[STATISTIC_NUM_SLOTS];
  	int2		statyplen[STATISTIC_NUM_SLOTS];
  	bool		statypbyval[STATISTIC_NUM_SLOTS];
  	char		statypalign[STATISTIC_NUM_SLOTS];
  
  	/*
  	 * These fields are private to the main ANALYZE code and should not be
  	 * looked at by type-specific functions.
  	 */
  	int			tupattnum;		/* attribute number within tuples */
  	HeapTuple  *rows;			/* access info for std fetch function */
  	TupleDesc	tupDesc;
  	Datum	   *exprvals;		/* access info for index fetch function */
  	bool	   *exprnulls;
  	int			rowstride;
  } VacAttrStats;
  
  
  /* GUC parameters */
  extern PGDLLIMPORT int default_statistics_target;		/* PGDLLIMPORT for
  														 * PostGIS */
  extern int	vacuum_freeze_min_age;
  extern int	vacuum_freeze_table_age;
  
  
  /* in commands/vacuum.c */
  extern void vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
  	   BufferAccessStrategy bstrategy, bool for_wraparound, bool isTopLevel);
  extern void vac_open_indexes(Relation relation, LOCKMODE lockmode,
  				 int *nindexes, Relation **Irel);
  extern void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode);
  extern void vac_update_relstats(Relation relation,
  					BlockNumber num_pages,
  					double num_tuples,
  					bool hasindex,
  					TransactionId frozenxid);
  extern void vacuum_set_xid_limits(int freeze_min_age, int freeze_table_age,
  					  bool sharedRel,
  					  TransactionId *oldestXmin,
  					  TransactionId *freezeLimit,
  					  TransactionId *freezeTableLimit);
  extern void vac_update_datfrozenxid(void);
  extern bool vac_is_partial_index(Relation indrel);
  extern void vacuum_delay_point(void);
  
  /* in commands/vacuumlazy.c */
  extern void lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
  				BufferAccessStrategy bstrategy, bool *scanned_all);
  
  /* in commands/analyze.c */
  extern void analyze_rel(Oid relid, VacuumStmt *vacstmt,
  			BufferAccessStrategy bstrategy, bool update_reltuples);
  
  #endif   /* VACUUM_H */
  