blob: 4a2b5510e7415d044bb75cddfe25804aaef5d4cd [file] [log] [blame]
/*-------------------------------------------------------------------------
*
* vacuum.h
* header file for postgres vacuum cleaner and statistics analyzer
*
*
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.68 2006/11/05 22:42:10 tgl 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/lock.h"
#include "utils/rel.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 PgStatistic
{
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];
} PgStatistic;
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.)
*/
PgStatistic pgstat;
/*
* 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;
/*
* The "vtlinks" array keeps information about each recently-updated tuple
* ("recent" meaning its XMAX is too new to let us recycle the tuple).
* We store the tuple's own TID as well as its t_ctid (its link to the next
* newer tuple version). Searching in this array allows us to follow update
* chains backwards from newer to older tuples. When we move a member of an
* update chain, we must move *all* the live members of the chain, so that we
* can maintain their t_ctid link relationships (we must not just overwrite
* t_ctid in an existing tuple).
*
* Note: because t_ctid links can be stale (this would only occur if a prior
* VACUUM crashed partway through), it is possible that new_tid points to an
* empty slot or unrelated tuple. We have to check the linkage as we follow
* it, just as is done in EvalPlanQual.
*/
typedef struct VTupleLinkData
{
ItemPointerData new_tid; /* t_ctid of an updated tuple */
ItemPointerData this_tid; /* t_self of the tuple */
} VTupleLinkData;
typedef VTupleLinkData *VTupleLink;
/*
* VRelStats contains the data acquired by scan_heap for use later
*/
typedef struct VRelStats
{
/* miscellaneous statistics */
BlockNumber rel_pages;
double rel_tuples;
Size min_tlen;
Size max_tlen;
bool hasindex;
/* vtlinks array for tuple chain following - sorted by new_tid */
int num_vtlinks;
VTupleLink vtlinks;
} VRelStats;
/* GUC parameters */
extern PGDLLIMPORT int default_statistics_target; /* PGDLLIMPORT for PostGIS */
extern PGDLLIMPORT double analyze_relative_error;
extern int vacuum_freeze_min_age;
/* in commands/vacuum.c */
extern void vacuum(VacuumStmt *vacstmt, List *relids, int preferred_seg_num);
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 rel,
BlockNumber num_pages,
double num_tuples,
bool hasindex,
TransactionId frozenxid,
List *updated_stats);
extern void vacuum_set_xid_limits(VacuumStmt *vacstmt, bool sharedRel,
TransactionId *oldestXmin,
TransactionId *freezeLimit);
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, List *updated_stats);
extern void vacuum_appendonly_rel(Relation aorel, void *vacrelstats, bool isVacFull);
extern void vacuum_parquet_rel(Relation parquetrel, void *vacrelstats, bool isVacFull);
extern void gen_oids_for_bitmaps(VacuumStmt *vacstmt, Relation onerel);
extern List *get_oids_for_bitmap(List *all_extra_oids, Relation Irel, Relation onerel, int occurrence);
/* in commands/analyze.c */
extern void analyzeStatement(VacuumStmt *vacstmt, List *relids, int preferred_seg_num);
extern void analyzeStmt(VacuumStmt *vacstmt, List *relids, int target_seg_num);
#endif /* VACUUM_H */