34#include "catalog/pg_am_d.h"
99 double dead_tuple_percent;
106 elog(
ERROR,
"return type must be a row type");
114 if (
stat->table_len == 0)
117 dead_tuple_percent = 0.0;
122 tuple_percent = 100.0 *
stat->tuple_len /
stat->table_len;
123 dead_tuple_percent = 100.0 *
stat->dead_tuple_len /
stat->table_len;
124 free_percent = 100.0 *
stat->free_space /
stat->table_len;
174 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
175 errmsg(
"must be superuser to use pgstattuple functions")));
214 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
215 errmsg(
"must be superuser to use pgstattuple functions")));
251 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
252 errmsg(
"cannot access temporary tables of other sessions")));
254 if (RELKIND_HAS_TABLE_AM(rel->
rd_rel->relkind) ||
255 rel->
rd_rel->relkind == RELKIND_SEQUENCE)
259 else if (rel->
rd_rel->relkind == RELKIND_INDEX)
264 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
265 errmsg(
"index \"%s\" is not valid",
268 switch (rel->
rd_rel->relam)
283 err =
"spgist index";
289 err =
"unknown index";
293 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
294 errmsg(
"index \"%s\" (%s) is not supported",
300 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
301 errmsg(
"cannot get tuple-level statistics for relation \"%s\"",
328 if (rel->
rd_rel->relkind != RELKIND_SEQUENCE &&
329 rel->
rd_rel->relam != HEAP_TABLE_AM_OID)
331 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
332 errmsg(
"only heap AM is supported")));
358 stat.dead_tuple_count++;
371 while (block <= tupblock)
384 while (block < nblocks)
422 stat->free_space += BLCKSZ;
432 stat->free_space += BLCKSZ;
469 stat->free_space += BLCKSZ;
542 if (blkno >= nblocks)
549 for (; blkno < nblocks; blkno++)
553 pagefn(&
stat, rel, blkno, bstrategy);
579 stat->dead_tuple_count++;
static Datum values[MAXATTR]
struct BufferAccessStrategyData * BufferAccessStrategy
void UnlockReleaseBuffer(Buffer buffer)
void LockBuffer(Buffer buffer, int mode)
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
#define BUFFER_LOCK_UNLOCK
#define BUFFER_LOCK_SHARE
#define RelationGetNumberOfBlocks(reln)
static Page BufferGetPage(Buffer buffer)
Size PageGetExactFreeSpace(const PageData *page)
static uint16 PageGetSpecialSize(const PageData *page)
static bool PageIsNew(const PageData *page)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void err(int eval, const char *fmt,...)
HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
AttInMetadata * TupleDescGetAttInMetadata(TupleDesc tupdesc)
#define PG_GETARG_TEXT_PP(n)
#define PG_RETURN_DATUM(x)
BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype)
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
#define GistPageIsLeaf(page)
void gistcheckpage(Relation rel, Buffer buf)
#define HashPageGetOpaque(page)
void _hash_relbuf(Relation rel, Buffer buf)
Buffer _hash_getbuf_with_strategy(Relation rel, BlockNumber blkno, int access, int flags, BufferAccessStrategy bstrategy)
HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction)
struct HeapScanDescData * HeapScanDesc
bool HeapTupleSatisfiesVisibility(HeapTuple htup, Snapshot snapshot, Buffer buffer)
#define ItemIdGetLength(itemId)
#define ItemIdIsDead(itemId)
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
void LockRelationForExtension(Relation relation, LOCKMODE lockmode)
void UnlockRelationForExtension(Relation relation, LOCKMODE lockmode)
#define CHECK_FOR_INTERRUPTS()
RangeVar * makeRangeVarFromNameList(const List *names)
void _bt_relbuf(Relation rel, Buffer buf)
#define BTPageGetOpaque(page)
#define P_FIRSTDATAKEY(opaque)
#define OffsetNumberNext(offsetNumber)
#define FirstOffsetNumber
int errdetail_relkind_not_supported(char relkind)
Datum pgstattuplebyid(PG_FUNCTION_ARGS)
static Datum pgstat_relation(Relation rel, FunctionCallInfo fcinfo)
static Datum pgstat_index(Relation rel, BlockNumber start, pgstat_page pagefn, FunctionCallInfo fcinfo)
static void pgstat_index_page(pgstattuple_type *stat, Page page, OffsetNumber minoff, OffsetNumber maxoff)
Datum pgstattuple_v1_5(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(pgstattuple)
static void pgstat_gist_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno, BufferAccessStrategy bstrategy)
struct pgstattuple_type pgstattuple_type
void(* pgstat_page)(pgstattuple_type *, Relation, BlockNumber, BufferAccessStrategy)
static Datum build_pgstattuple_type(pgstattuple_type *stat, FunctionCallInfo fcinfo)
static void pgstat_btree_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno, BufferAccessStrategy bstrategy)
Datum pgstattuplebyid_v1_5(PG_FUNCTION_ARGS)
static Datum pgstat_heap(Relation rel, FunctionCallInfo fcinfo)
Datum pgstattuple(PG_FUNCTION_ARGS)
static void pgstat_hash_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno, BufferAccessStrategy bstrategy)
#define RelationGetRelationName(relation)
#define RELATION_IS_OTHER_TEMP(relation)
struct RelationData * Relation
#define InitDirtySnapshot(snapshotdata)
void relation_close(Relation relation, LOCKMODE lockmode)
Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
Relation relation_open(Oid relationId, LOCKMODE lockmode)
BufferAccessStrategy rs_strategy
static void table_endscan(TableScanDesc scan)
static TableScanDesc table_beginscan_strat(Relation rel, Snapshot snapshot, int nkeys, struct ScanKeyData *key, bool allow_strat, bool allow_sync)
List * textToQualifiedNameList(text *textval)