PostgreSQL Source Code  git master
pgstattuple.c File Reference
#include "postgres.h"
#include "access/gist_private.h"
#include "access/hash.h"
#include "access/heapam.h"
#include "access/nbtree.h"
#include "access/relscan.h"
#include "access/tableam.h"
#include "catalog/namespace.h"
#include "catalog/pg_am_d.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "storage/bufmgr.h"
#include "storage/lmgr.h"
#include "utils/builtins.h"
#include "utils/varlena.h"
Include dependency graph for pgstattuple.c:

Go to the source code of this file.

Data Structures

struct  pgstattuple_type
 

Macros

#define NCOLUMNS   9
 
#define NCHARS   314
 

Typedefs

typedef struct pgstattuple_type pgstattuple_type
 
typedef void(* pgstat_page) (pgstattuple_type *, Relation, BlockNumber, BufferAccessStrategy)
 

Functions

 PG_FUNCTION_INFO_V1 (pgstattuple)
 
 PG_FUNCTION_INFO_V1 (pgstattuple_v1_5)
 
 PG_FUNCTION_INFO_V1 (pgstattuplebyid)
 
 PG_FUNCTION_INFO_V1 (pgstattuplebyid_v1_5)
 
static Datum build_pgstattuple_type (pgstattuple_type *stat, FunctionCallInfo fcinfo)
 
static Datum pgstat_relation (Relation rel, FunctionCallInfo fcinfo)
 
static Datum pgstat_heap (Relation rel, FunctionCallInfo fcinfo)
 
static void pgstat_btree_page (pgstattuple_type *stat, Relation rel, BlockNumber blkno, BufferAccessStrategy bstrategy)
 
static void pgstat_hash_page (pgstattuple_type *stat, Relation rel, BlockNumber blkno, BufferAccessStrategy bstrategy)
 
static void pgstat_gist_page (pgstattuple_type *stat, Relation rel, BlockNumber blkno, BufferAccessStrategy bstrategy)
 
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 (PG_FUNCTION_ARGS)
 
Datum pgstattuple_v1_5 (PG_FUNCTION_ARGS)
 
Datum pgstattuplebyid (PG_FUNCTION_ARGS)
 
Datum pgstattuplebyid_v1_5 (PG_FUNCTION_ARGS)
 

Variables

 PG_MODULE_MAGIC
 

Macro Definition Documentation

◆ NCHARS

#define NCHARS   314

Referenced by build_pgstattuple_type().

◆ NCOLUMNS

#define NCOLUMNS   9

Referenced by build_pgstattuple_type().

Typedef Documentation

◆ pgstat_page

typedef void(* pgstat_page) (pgstattuple_type *, Relation, BlockNumber, BufferAccessStrategy)

Definition at line 65 of file pgstattuple.c.

◆ pgstattuple_type

Function Documentation

◆ build_pgstattuple_type()

static Datum build_pgstattuple_type ( pgstattuple_type stat,
FunctionCallInfo  fcinfo 
)
static

Definition at line 90 of file pgstattuple.c.

References BuildTupleFromCStrings(), pgstattuple_type::dead_tuple_count, pgstattuple_type::dead_tuple_len, elog, ERROR, pgstattuple_type::free_space, get_call_result_type(), HeapTupleGetDatum, i, INT64_FORMAT, NCHARS, NCOLUMNS, snprintf, pgstattuple_type::table_len, pgstattuple_type::tuple_count, pgstattuple_type::tuple_len, TupleDescGetAttInMetadata(), TYPEFUNC_COMPOSITE, and values.

Referenced by pgstat_heap(), and pgstat_index().

91 {
92 #define NCOLUMNS 9
93 #define NCHARS 314
94 
95  HeapTuple tuple;
96  char *values[NCOLUMNS];
97  char values_buf[NCOLUMNS][NCHARS];
98  int i;
99  double tuple_percent;
100  double dead_tuple_percent;
101  double free_percent; /* free/reusable space in % */
102  TupleDesc tupdesc;
103  AttInMetadata *attinmeta;
104 
105  /* Build a tuple descriptor for our result type */
106  if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
107  elog(ERROR, "return type must be a row type");
108 
109  /*
110  * Generate attribute metadata needed later to produce tuples from raw C
111  * strings
112  */
113  attinmeta = TupleDescGetAttInMetadata(tupdesc);
114 
115  if (stat->table_len == 0)
116  {
117  tuple_percent = 0.0;
118  dead_tuple_percent = 0.0;
119  free_percent = 0.0;
120  }
121  else
122  {
123  tuple_percent = 100.0 * stat->tuple_len / stat->table_len;
124  dead_tuple_percent = 100.0 * stat->dead_tuple_len / stat->table_len;
125  free_percent = 100.0 * stat->free_space / stat->table_len;
126  }
127 
128  /*
129  * Prepare a values array for constructing the tuple. This should be an
130  * array of C strings which will be processed later by the appropriate
131  * "in" functions.
132  */
133  for (i = 0; i < NCOLUMNS; i++)
134  values[i] = values_buf[i];
135  i = 0;
136  snprintf(values[i++], NCHARS, INT64_FORMAT, stat->table_len);
137  snprintf(values[i++], NCHARS, INT64_FORMAT, stat->tuple_count);
138  snprintf(values[i++], NCHARS, INT64_FORMAT, stat->tuple_len);
139  snprintf(values[i++], NCHARS, "%.2f", tuple_percent);
140  snprintf(values[i++], NCHARS, INT64_FORMAT, stat->dead_tuple_count);
141  snprintf(values[i++], NCHARS, INT64_FORMAT, stat->dead_tuple_len);
142  snprintf(values[i++], NCHARS, "%.2f", dead_tuple_percent);
143  snprintf(values[i++], NCHARS, INT64_FORMAT, stat->free_space);
144  snprintf(values[i++], NCHARS, "%.2f", free_percent);
145 
146  /* build a tuple */
147  tuple = BuildTupleFromCStrings(attinmeta, values);
148 
149  /* make the tuple into a datum */
150  return HeapTupleGetDatum(tuple);
151 }
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:207
#define NCOLUMNS
uint64 dead_tuple_count
Definition: pgstattuple.c:60
HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
Definition: execTuples.c:2146
uint64 dead_tuple_len
Definition: pgstattuple.c:61
#define ERROR
Definition: elog.h:46
#define NCHARS
AttInMetadata * TupleDescGetAttInMetadata(TupleDesc tupdesc)
Definition: execTuples.c:2097
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:220
#define INT64_FORMAT
Definition: c.h:483
static Datum values[MAXATTR]
Definition: bootstrap.c:156
#define elog(elevel,...)
Definition: elog.h:232
int i
#define snprintf
Definition: port.h:217
uint64 tuple_count
Definition: pgstattuple.c:58

◆ PG_FUNCTION_INFO_V1() [1/4]

PG_FUNCTION_INFO_V1 ( pgstattuple  )

◆ PG_FUNCTION_INFO_V1() [2/4]

PG_FUNCTION_INFO_V1 ( pgstattuple_v1_5  )

◆ PG_FUNCTION_INFO_V1() [3/4]

PG_FUNCTION_INFO_V1 ( pgstattuplebyid  )

◆ PG_FUNCTION_INFO_V1() [4/4]

PG_FUNCTION_INFO_V1 ( pgstattuplebyid_v1_5  )

◆ pgstat_btree_page()

static void pgstat_btree_page ( pgstattuple_type stat,
Relation  rel,
BlockNumber  blkno,
BufferAccessStrategy  bstrategy 
)
static

Definition at line 399 of file pgstattuple.c.

References _bt_relbuf(), BT_READ, buf, BufferGetPage, pgstattuple_type::free_space, LockBuffer(), MAIN_FORKNUM, P_FIRSTDATAKEY, P_IGNORE, P_ISLEAF, PageGetMaxOffsetNumber, PageGetSpecialPointer, PageIsNew, pgstat_index_page(), RBM_NORMAL, and ReadBufferExtended().

Referenced by pgstat_relation().

401 {
402  Buffer buf;
403  Page page;
404 
405  buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy);
406  LockBuffer(buf, BT_READ);
407  page = BufferGetPage(buf);
408 
409  /* Page is valid, see what to do with it */
410  if (PageIsNew(page))
411  {
412  /* fully empty page */
413  stat->free_space += BLCKSZ;
414  }
415  else
416  {
417  BTPageOpaque opaque;
418 
419  opaque = (BTPageOpaque) PageGetSpecialPointer(page);
420  if (P_IGNORE(opaque))
421  {
422  /* deleted or half-dead page */
423  stat->free_space += BLCKSZ;
424  }
425  else if (P_ISLEAF(opaque))
426  {
427  pgstat_index_page(stat, page, P_FIRSTDATAKEY(opaque),
428  PageGetMaxOffsetNumber(page));
429  }
430  else
431  {
432  /* internal page */
433  }
434  }
435 
436  _bt_relbuf(rel, buf);
437 }
#define P_IGNORE(opaque)
Definition: nbtree.h:224
#define P_FIRSTDATAKEY(opaque)
Definition: nbtree.h:369
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition: bufmgr.c:741
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:357
BTPageOpaqueData * BTPageOpaque
Definition: nbtree.h:71
#define BT_READ
Definition: nbtree.h:712
static char * buf
Definition: pg_test_fsync.c:68
#define BufferGetPage(buffer)
Definition: bufmgr.h:169
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:4007
void _bt_relbuf(Relation rel, Buffer buf)
Definition: nbtpage.c:1035
#define PageGetSpecialPointer(page)
Definition: bufpage.h:326
static void pgstat_index_page(pgstattuple_type *stat, Page page, OffsetNumber minoff, OffsetNumber maxoff)
Definition: pgstattuple.c:557
#define PageIsNew(page)
Definition: bufpage.h:229
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:78
#define P_ISLEAF(opaque)
Definition: nbtree.h:219

◆ pgstat_gist_page()

static void pgstat_gist_page ( pgstattuple_type stat,
Relation  rel,
BlockNumber  blkno,
BufferAccessStrategy  bstrategy 
)
static

Definition at line 485 of file pgstattuple.c.

References buf, BufferGetPage, FirstOffsetNumber, GIST_SHARE, gistcheckpage(), GistPageIsLeaf, LockBuffer(), MAIN_FORKNUM, PageGetMaxOffsetNumber, pgstat_index_page(), RBM_NORMAL, ReadBufferExtended(), and UnlockReleaseBuffer().

Referenced by pgstat_relation().

487 {
488  Buffer buf;
489  Page page;
490 
491  buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy);
492  LockBuffer(buf, GIST_SHARE);
493  gistcheckpage(rel, buf);
494  page = BufferGetPage(buf);
495 
496  if (GistPageIsLeaf(page))
497  {
499  PageGetMaxOffsetNumber(page));
500  }
501  else
502  {
503  /* root or node */
504  }
505 
506  UnlockReleaseBuffer(buf);
507 }
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition: bufmgr.c:741
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:357
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3791
static char * buf
Definition: pg_test_fsync.c:68
#define FirstOffsetNumber
Definition: off.h:27
#define BufferGetPage(buffer)
Definition: bufmgr.h:169
#define GistPageIsLeaf(page)
Definition: gist.h:169
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:4007
void gistcheckpage(Relation rel, Buffer buf)
Definition: gistutil.c:784
#define GIST_SHARE
Definition: gist_private.h:42
static void pgstat_index_page(pgstattuple_type *stat, Page page, OffsetNumber minoff, OffsetNumber maxoff)
Definition: pgstattuple.c:557
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:78

◆ pgstat_hash_page()

static void pgstat_hash_page ( pgstattuple_type stat,
Relation  rel,
BlockNumber  blkno,
BufferAccessStrategy  bstrategy 
)
static

Definition at line 443 of file pgstattuple.c.

References _hash_getbuf_with_strategy(), _hash_relbuf(), buf, BufferGetPage, FirstOffsetNumber, pgstattuple_type::free_space, HASH_READ, HashPageOpaqueData::hasho_flag, LH_BITMAP_PAGE, LH_BUCKET_PAGE, LH_META_PAGE, LH_OVERFLOW_PAGE, LH_PAGE_TYPE, LH_UNUSED_PAGE, MAXALIGN, PageGetMaxOffsetNumber, PageGetSpecialPointer, PageGetSpecialSize, and pgstat_index_page().

Referenced by pgstat_relation().

445 {
446  Buffer buf;
447  Page page;
448 
449  buf = _hash_getbuf_with_strategy(rel, blkno, HASH_READ, 0, bstrategy);
450  page = BufferGetPage(buf);
451 
452  if (PageGetSpecialSize(page) == MAXALIGN(sizeof(HashPageOpaqueData)))
453  {
454  HashPageOpaque opaque;
455 
456  opaque = (HashPageOpaque) PageGetSpecialPointer(page);
457  switch (opaque->hasho_flag & LH_PAGE_TYPE)
458  {
459  case LH_UNUSED_PAGE:
460  stat->free_space += BLCKSZ;
461  break;
462  case LH_BUCKET_PAGE:
463  case LH_OVERFLOW_PAGE:
465  PageGetMaxOffsetNumber(page));
466  break;
467  case LH_BITMAP_PAGE:
468  case LH_META_PAGE:
469  default:
470  break;
471  }
472  }
473  else
474  {
475  /* maybe corrupted */
476  }
477 
478  _hash_relbuf(rel, buf);
479 }
#define LH_BITMAP_PAGE
Definition: hash.h:56
#define LH_META_PAGE
Definition: hash.h:57
Buffer _hash_getbuf_with_strategy(Relation rel, BlockNumber blkno, int access, int flags, BufferAccessStrategy bstrategy)
Definition: hashpage.c:238
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:357
#define LH_UNUSED_PAGE
Definition: hash.h:53
#define LH_PAGE_TYPE
Definition: hash.h:63
#define HASH_READ
Definition: hash.h:337
static char * buf
Definition: pg_test_fsync.c:68
#define FirstOffsetNumber
Definition: off.h:27
#define BufferGetPage(buffer)
Definition: bufmgr.h:169
#define LH_OVERFLOW_PAGE
Definition: hash.h:54
void _hash_relbuf(Relation rel, Buffer buf)
Definition: hashpage.c:265
#define LH_BUCKET_PAGE
Definition: hash.h:55
#define PageGetSpecialPointer(page)
Definition: bufpage.h:326
HashPageOpaqueData * HashPageOpaque
Definition: hash.h:86
#define MAXALIGN(LEN)
Definition: c.h:757
#define PageGetSpecialSize(page)
Definition: bufpage.h:300
static void pgstat_index_page(pgstattuple_type *stat, Page page, OffsetNumber minoff, OffsetNumber maxoff)
Definition: pgstattuple.c:557
uint16 hasho_flag
Definition: hash.h:82
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:78

◆ pgstat_heap()

static Datum pgstat_heap ( Relation  rel,
FunctionCallInfo  fcinfo 
)
static

Definition at line 308 of file pgstattuple.c.

References AccessShareLock, BUFFER_LOCK_SHARE, BUFFER_LOCK_UNLOCK, BufferGetPage, build_pgstattuple_type(), CHECK_FOR_INTERRUPTS, pgstattuple_type::dead_tuple_count, pgstattuple_type::dead_tuple_len, ereport, errcode(), errmsg(), ERROR, ForwardScanDirection, pgstattuple_type::free_space, heap_getnext(), HeapTupleSatisfiesVisibility(), InitDirtySnapshot, ItemPointerGetBlockNumber, LockBuffer(), MAIN_FORKNUM, PageGetHeapFreeSpace(), RBM_NORMAL, RelationData::rd_rel, ReadBufferExtended(), relation_close(), HeapScanDescData::rs_cbuf, HeapScanDescData::rs_nblocks, HeapScanDescData::rs_strategy, SnapshotAny, HeapTupleData::t_len, HeapTupleData::t_self, table_beginscan_strat(), table_endscan(), pgstattuple_type::table_len, pgstattuple_type::tuple_count, pgstattuple_type::tuple_len, and UnlockReleaseBuffer().

Referenced by pgstat_relation().

309 {
310  TableScanDesc scan;
311  HeapScanDesc hscan;
312  HeapTuple tuple;
313  BlockNumber nblocks;
314  BlockNumber block = 0; /* next block to count free space in */
315  BlockNumber tupblock;
316  Buffer buffer;
317  pgstattuple_type stat = {0};
318  SnapshotData SnapshotDirty;
319 
320  if (rel->rd_rel->relam != HEAP_TABLE_AM_OID)
321  ereport(ERROR,
322  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
323  errmsg("only heap AM is supported")));
324 
325  /* Disable syncscan because we assume we scan from block zero upwards */
326  scan = table_beginscan_strat(rel, SnapshotAny, 0, NULL, true, false);
327  hscan = (HeapScanDesc) scan;
328 
329  InitDirtySnapshot(SnapshotDirty);
330 
331  nblocks = hscan->rs_nblocks; /* # blocks to be scanned */
332 
333  /* scan the relation */
334  while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
335  {
337 
338  /* must hold a buffer lock to call HeapTupleSatisfiesVisibility */
340 
341  if (HeapTupleSatisfiesVisibility(tuple, &SnapshotDirty, hscan->rs_cbuf))
342  {
343  stat.tuple_len += tuple->t_len;
344  stat.tuple_count++;
345  }
346  else
347  {
348  stat.dead_tuple_len += tuple->t_len;
349  stat.dead_tuple_count++;
350  }
351 
353 
354  /*
355  * To avoid physically reading the table twice, try to do the
356  * free-space scan in parallel with the heap scan. However,
357  * heap_getnext may find no tuples on a given page, so we cannot
358  * simply examine the pages returned by the heap scan.
359  */
360  tupblock = ItemPointerGetBlockNumber(&tuple->t_self);
361 
362  while (block <= tupblock)
363  {
365 
366  buffer = ReadBufferExtended(rel, MAIN_FORKNUM, block,
367  RBM_NORMAL, hscan->rs_strategy);
368  LockBuffer(buffer, BUFFER_LOCK_SHARE);
370  UnlockReleaseBuffer(buffer);
371  block++;
372  }
373  }
374 
375  while (block < nblocks)
376  {
378 
379  buffer = ReadBufferExtended(rel, MAIN_FORKNUM, block,
380  RBM_NORMAL, hscan->rs_strategy);
381  LockBuffer(buffer, BUFFER_LOCK_SHARE);
383  UnlockReleaseBuffer(buffer);
384  block++;
385  }
386 
387  table_endscan(scan);
389 
390  stat.table_len = (uint64) nblocks * BLCKSZ;
391 
392  return build_pgstattuple_type(&stat, fcinfo);
393 }
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:96
#define InitDirtySnapshot(snapshotdata)
Definition: snapmgr.h:74
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition: bufmgr.c:741
uint64 dead_tuple_count
Definition: pgstattuple.c:60
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:698
uint32 BlockNumber
Definition: block.h:31
Form_pg_class rd_rel
Definition: rel.h:109
static TableScanDesc table_beginscan_strat(Relation rel, Snapshot snapshot, int nkeys, struct ScanKeyData *key, bool allow_strat, bool allow_sync)
Definition: tableam.h:907
struct HeapScanDescData * HeapScanDesc
Definition: heapam.h:79
uint64 dead_tuple_len
Definition: pgstattuple.c:61
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3791
#define ERROR
Definition: elog.h:46
Size PageGetHeapFreeSpace(Page page)
Definition: bufpage.c:984
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction)
Definition: heapam.c:1340
#define BufferGetPage(buffer)
Definition: bufmgr.h:169
BlockNumber rs_nblocks
Definition: heapam.h:52
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:4007
BufferAccessStrategy rs_strategy
Definition: heapam.h:64
#define ereport(elevel,...)
Definition: elog.h:157
Buffer rs_cbuf
Definition: heapam.h:60
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: relation.c:206
#define SnapshotAny
Definition: snapmgr.h:67
static void table_endscan(TableScanDesc scan)
Definition: tableam.h:991
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:97
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:120
#define ItemPointerGetBlockNumber(pointer)
Definition: itemptr.h:98
static Datum build_pgstattuple_type(pgstattuple_type *stat, FunctionCallInfo fcinfo)
Definition: pgstattuple.c:90
int Buffer
Definition: buf.h:23
uint64 tuple_count
Definition: pgstattuple.c:58
Pointer Page
Definition: bufpage.h:78
bool HeapTupleSatisfiesVisibility(HeapTuple tup, Snapshot snapshot, Buffer buffer)

◆ pgstat_index()

static Datum pgstat_index ( Relation  rel,
BlockNumber  start,
pgstat_page  pagefn,
FunctionCallInfo  fcinfo 
)
static

Definition at line 513 of file pgstattuple.c.

References AccessShareLock, BAS_BULKREAD, build_pgstattuple_type(), CHECK_FOR_INTERRUPTS, ExclusiveLock, GetAccessStrategy(), LockRelationForExtension(), relation_close(), RelationGetNumberOfBlocks, pgstattuple_type::table_len, and UnlockRelationForExtension().

Referenced by pgstat_relation().

515 {
516  BlockNumber nblocks;
517  BlockNumber blkno;
518  BufferAccessStrategy bstrategy;
519  pgstattuple_type stat = {0};
520 
521  /* prepare access strategy for this index */
522  bstrategy = GetAccessStrategy(BAS_BULKREAD);
523 
524  blkno = start;
525  for (;;)
526  {
527  /* Get the current relation length */
529  nblocks = RelationGetNumberOfBlocks(rel);
531 
532  /* Quit if we've scanned the whole relation */
533  if (blkno >= nblocks)
534  {
535  stat.table_len = (uint64) nblocks * BLCKSZ;
536 
537  break;
538  }
539 
540  for (; blkno < nblocks; blkno++)
541  {
543 
544  pagefn(&stat, rel, blkno, bstrategy);
545  }
546  }
547 
549 
550  return build_pgstattuple_type(&stat, fcinfo);
551 }
BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype)
Definition: freelist.c:542
#define ExclusiveLock
Definition: lockdefs.h:44
#define AccessShareLock
Definition: lockdefs.h:36
uint32 BlockNumber
Definition: block.h:31
void LockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:403
void UnlockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:453
#define RelationGetNumberOfBlocks(reln)
Definition: bufmgr.h:212
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: relation.c:206
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:120
static Datum build_pgstattuple_type(pgstattuple_type *stat, FunctionCallInfo fcinfo)
Definition: pgstattuple.c:90

◆ pgstat_index_page()

static void pgstat_index_page ( pgstattuple_type stat,
Page  page,
OffsetNumber  minoff,
OffsetNumber  maxoff 
)
static

Definition at line 557 of file pgstattuple.c.

References pgstattuple_type::dead_tuple_count, pgstattuple_type::dead_tuple_len, pgstattuple_type::free_space, i, ItemIdGetLength, ItemIdIsDead, OffsetNumberNext, PageGetFreeSpace(), PageGetItemId, pgstattuple_type::tuple_count, and pgstattuple_type::tuple_len.

Referenced by pgstat_btree_page(), pgstat_gist_page(), and pgstat_hash_page().

559 {
560  OffsetNumber i;
561 
562  stat->free_space += PageGetFreeSpace(page);
563 
564  for (i = minoff; i <= maxoff; i = OffsetNumberNext(i))
565  {
566  ItemId itemid = PageGetItemId(page, i);
567 
568  if (ItemIdIsDead(itemid))
569  {
570  stat->dead_tuple_count++;
571  stat->dead_tuple_len += ItemIdGetLength(itemid);
572  }
573  else
574  {
575  stat->tuple_count++;
576  stat->tuple_len += ItemIdGetLength(itemid);
577  }
578  }
579 }
uint64 dead_tuple_count
Definition: pgstattuple.c:60
#define ItemIdIsDead(itemId)
Definition: itemid.h:113
Size PageGetFreeSpace(Page page)
Definition: bufpage.c:900
uint16 OffsetNumber
Definition: off.h:24
uint64 dead_tuple_len
Definition: pgstattuple.c:61
#define ItemIdGetLength(itemId)
Definition: itemid.h:59
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:235
#define OffsetNumberNext(offsetNumber)
Definition: off.h:52
int i
uint64 tuple_count
Definition: pgstattuple.c:58

◆ pgstat_relation()

static Datum pgstat_relation ( Relation  rel,
FunctionCallInfo  fcinfo 
)
static

Definition at line 241 of file pgstattuple.c.

References BTREE_METAPAGE, ereport, errcode(), errdetail_relkind_not_supported(), errmsg(), ERROR, GIST_ROOT_BLKNO, HASH_METAPAGE, pgstat_btree_page(), pgstat_gist_page(), pgstat_hash_page(), pgstat_heap(), pgstat_index(), RelationData::rd_rel, RELATION_IS_OTHER_TEMP, and RelationGetRelationName.

Referenced by pgstattuple(), pgstattuple_v1_5(), pgstattuplebyid(), and pgstattuplebyid_v1_5().

242 {
243  const char *err;
244 
245  /*
246  * Reject attempts to read non-local temporary relations; we would be
247  * likely to get wrong data since we have no visibility into the owning
248  * session's local buffers.
249  */
250  if (RELATION_IS_OTHER_TEMP(rel))
251  ereport(ERROR,
252  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
253  errmsg("cannot access temporary tables of other sessions")));
254 
255  switch (rel->rd_rel->relkind)
256  {
257  case RELKIND_RELATION:
258  case RELKIND_MATVIEW:
259  case RELKIND_TOASTVALUE:
260  case RELKIND_SEQUENCE:
261  return pgstat_heap(rel, fcinfo);
262  case RELKIND_INDEX:
263  switch (rel->rd_rel->relam)
264  {
265  case BTREE_AM_OID:
266  return pgstat_index(rel, BTREE_METAPAGE + 1,
267  pgstat_btree_page, fcinfo);
268  case HASH_AM_OID:
269  return pgstat_index(rel, HASH_METAPAGE + 1,
270  pgstat_hash_page, fcinfo);
271  case GIST_AM_OID:
272  return pgstat_index(rel, GIST_ROOT_BLKNO + 1,
273  pgstat_gist_page, fcinfo);
274  case GIN_AM_OID:
275  err = "gin index";
276  break;
277  case SPGIST_AM_OID:
278  err = "spgist index";
279  break;
280  case BRIN_AM_OID:
281  err = "brin index";
282  break;
283  default:
284  err = "unknown index";
285  break;
286  }
287  ereport(ERROR,
288  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
289  errmsg("index \"%s\" (%s) is not supported",
290  RelationGetRelationName(rel), err)));
291  break;
292 
293  default:
294  ereport(ERROR,
295  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
296  errmsg("cannot get tuple-level statistics for relation \"%s\"",
298  errdetail_relkind_not_supported(rel->rd_rel->relkind)));
299  }
300 
301  return 0; /* should not happen */
302 }
int errdetail_relkind_not_supported(char relkind)
Definition: pg_class.c:24
static void pgstat_hash_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno, BufferAccessStrategy bstrategy)
Definition: pgstattuple.c:443
static void pgstat_btree_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno, BufferAccessStrategy bstrategy)
Definition: pgstattuple.c:399
int err
Definition: px.c:38
int errcode(int sqlerrcode)
Definition: elog.c:698
Form_pg_class rd_rel
Definition: rel.h:109
#define ERROR
Definition: elog.h:46
#define RelationGetRelationName(relation)
Definition: rel.h:511
#define BTREE_METAPAGE
Definition: nbtree.h:146
static Datum pgstat_heap(Relation rel, FunctionCallInfo fcinfo)
Definition: pgstattuple.c:308
#define HASH_METAPAGE
Definition: hash.h:196
static Datum pgstat_index(Relation rel, BlockNumber start, pgstat_page pagefn, FunctionCallInfo fcinfo)
Definition: pgstattuple.c:513
#define ereport(elevel,...)
Definition: elog.h:157
#define RELATION_IS_OTHER_TEMP(relation)
Definition: rel.h:631
static void pgstat_gist_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno, BufferAccessStrategy bstrategy)
Definition: pgstattuple.c:485
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define GIST_ROOT_BLKNO
Definition: gist_private.h:262

◆ pgstattuple()

Datum pgstattuple ( PG_FUNCTION_ARGS  )

Definition at line 167 of file pgstattuple.c.

References AccessShareLock, ereport, errcode(), errmsg(), ERROR, makeRangeVarFromNameList(), PG_GETARG_TEXT_PP, PG_RETURN_DATUM, pgstat_relation(), relation_openrv(), relname, superuser(), and textToQualifiedNameList().

168 {
170  RangeVar *relrv;
171  Relation rel;
172 
173  if (!superuser())
174  ereport(ERROR,
175  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
176  errmsg("must be superuser to use pgstattuple functions")));
177 
178  /* open relation */
180  rel = relation_openrv(relrv, AccessShareLock);
181 
182  PG_RETURN_DATUM(pgstat_relation(rel, fcinfo));
183 }
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:698
bool superuser(void)
Definition: superuser.c:46
RangeVar * makeRangeVarFromNameList(List *names)
Definition: namespace.c:3107
NameData relname
Definition: pg_class.h:38
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define ERROR
Definition: elog.h:46
List * textToQualifiedNameList(text *textval)
Definition: varlena.c:3688
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
Definition: relation.c:138
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
Definition: c.h:621
static Datum pgstat_relation(Relation rel, FunctionCallInfo fcinfo)
Definition: pgstattuple.c:241

◆ pgstattuple_v1_5()

Datum pgstattuple_v1_5 ( PG_FUNCTION_ARGS  )

Definition at line 193 of file pgstattuple.c.

References AccessShareLock, makeRangeVarFromNameList(), PG_GETARG_TEXT_PP, PG_RETURN_DATUM, pgstat_relation(), relation_openrv(), relname, and textToQualifiedNameList().

194 {
196  RangeVar *relrv;
197  Relation rel;
198 
199  /* open relation */
201  rel = relation_openrv(relrv, AccessShareLock);
202 
203  PG_RETURN_DATUM(pgstat_relation(rel, fcinfo));
204 }
#define AccessShareLock
Definition: lockdefs.h:36
RangeVar * makeRangeVarFromNameList(List *names)
Definition: namespace.c:3107
NameData relname
Definition: pg_class.h:38
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
List * textToQualifiedNameList(text *textval)
Definition: varlena.c:3688
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
Definition: relation.c:138
Definition: c.h:621
static Datum pgstat_relation(Relation rel, FunctionCallInfo fcinfo)
Definition: pgstattuple.c:241

◆ pgstattuplebyid()

Datum pgstattuplebyid ( PG_FUNCTION_ARGS  )

Definition at line 208 of file pgstattuple.c.

References AccessShareLock, ereport, errcode(), errmsg(), ERROR, PG_GETARG_OID, PG_RETURN_DATUM, pgstat_relation(), relation_open(), and superuser().

209 {
210  Oid relid = PG_GETARG_OID(0);
211  Relation rel;
212 
213  if (!superuser())
214  ereport(ERROR,
215  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
216  errmsg("must be superuser to use pgstattuple functions")));
217 
218  /* open relation */
219  rel = relation_open(relid, AccessShareLock);
220 
221  PG_RETURN_DATUM(pgstat_relation(rel, fcinfo));
222 }
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:698
bool superuser(void)
Definition: superuser.c:46
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:46
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: relation.c:48
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
static Datum pgstat_relation(Relation rel, FunctionCallInfo fcinfo)
Definition: pgstattuple.c:241

◆ pgstattuplebyid_v1_5()

Datum pgstattuplebyid_v1_5 ( PG_FUNCTION_ARGS  )

Definition at line 226 of file pgstattuple.c.

References AccessShareLock, PG_GETARG_OID, PG_RETURN_DATUM, pgstat_relation(), and relation_open().

227 {
228  Oid relid = PG_GETARG_OID(0);
229  Relation rel;
230 
231  /* open relation */
232  rel = relation_open(relid, AccessShareLock);
233 
234  PG_RETURN_DATUM(pgstat_relation(rel, fcinfo));
235 }
#define AccessShareLock
Definition: lockdefs.h:36
unsigned int Oid
Definition: postgres_ext.h:31
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: relation.c:48
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
static Datum pgstat_relation(Relation rel, FunctionCallInfo fcinfo)
Definition: pgstattuple.c:241

Variable Documentation

◆ PG_MODULE_MAGIC

PG_MODULE_MAGIC

Definition at line 42 of file pgstattuple.c.