34#include "catalog/pg_am_d.h"
42 .
name =
"pgstattuple",
101 double tuple_percent;
102 double dead_tuple_percent;
109 elog(
ERROR,
"return type must be a row type");
117 if (
stat->table_len == 0)
120 dead_tuple_percent = 0.0;
125 tuple_percent = 100.0 *
stat->tuple_len /
stat->table_len;
126 dead_tuple_percent = 100.0 *
stat->dead_tuple_len /
stat->table_len;
127 free_percent = 100.0 *
stat->free_space /
stat->table_len;
177 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
178 errmsg(
"must be superuser to use pgstattuple functions")));
217 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
218 errmsg(
"must be superuser to use pgstattuple functions")));
254 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
255 errmsg(
"cannot access temporary tables of other sessions")));
257 if (RELKIND_HAS_TABLE_AM(rel->
rd_rel->relkind) ||
258 rel->
rd_rel->relkind == RELKIND_SEQUENCE)
262 else if (rel->
rd_rel->relkind == RELKIND_INDEX)
267 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
268 errmsg(
"index \"%s\" is not valid",
271 switch (rel->
rd_rel->relam)
286 err =
"spgist index";
292 err =
"unknown index";
296 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
297 errmsg(
"index \"%s\" (%s) is not supported",
303 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
304 errmsg(
"cannot get tuple-level statistics for relation \"%s\"",
331 if (rel->
rd_rel->relkind != RELKIND_SEQUENCE &&
332 rel->
rd_rel->relam != HEAP_TABLE_AM_OID)
334 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
335 errmsg(
"only heap AM is supported")));
361 stat.dead_tuple_count++;
374 while (block <= tupblock)
387 while (block < nblocks)
425 stat->free_space += BLCKSZ;
435 stat->free_space += BLCKSZ;
472 stat->free_space += BLCKSZ;
545 if (blkno >= nblocks)
552 for (; blkno < nblocks; blkno++)
556 pagefn(&
stat, rel, blkno, bstrategy);
582 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)
PG_MODULE_MAGIC_EXT(.name="pgstattuple",.version=PG_VERSION)
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)