PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pgstattuple.c
Go to the documentation of this file.
1 /*
2  * contrib/pgstattuple/pgstattuple.c
3  *
4  * Copyright (c) 2001,2002 Tatsuo Ishii
5  *
6  * Permission to use, copy, modify, and distribute this software and
7  * its documentation for any purpose, without fee, and without a
8  * written agreement is hereby granted, provided that the above
9  * copyright notice and this paragraph and the following two
10  * paragraphs appear in all copies.
11  *
12  * IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT,
13  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
14  * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
15  * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED
16  * OF THE POSSIBILITY OF SUCH DAMAGE.
17  *
18  * THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20  * A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS
21  * IS" BASIS, AND THE AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE,
22  * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23  */
24 
25 #include "postgres.h"
26 
27 #include "access/gist_private.h"
28 #include "access/hash.h"
29 #include "access/nbtree.h"
30 #include "access/relscan.h"
31 #include "catalog/namespace.h"
32 #include "catalog/pg_am.h"
33 #include "funcapi.h"
34 #include "miscadmin.h"
35 #include "storage/bufmgr.h"
36 #include "storage/lmgr.h"
37 #include "utils/builtins.h"
38 #include "utils/tqual.h"
39 #include "utils/varlena.h"
40 
42 
47 
48 /*
49  * struct pgstattuple_type
50  *
51  * tuple_percent, dead_tuple_percent and free_percent are computable,
52  * so not defined here.
53  */
54 typedef struct pgstattuple_type
55 {
56  uint64 table_len;
57  uint64 tuple_count;
58  uint64 tuple_len;
61  uint64 free_space; /* free/reusable space in bytes */
63 
66 
68  FunctionCallInfo fcinfo);
70 static Datum pgstat_heap(Relation rel, FunctionCallInfo fcinfo);
71 static void pgstat_btree_page(pgstattuple_type *stat,
72  Relation rel, BlockNumber blkno,
73  BufferAccessStrategy bstrategy);
74 static void pgstat_hash_page(pgstattuple_type *stat,
75  Relation rel, BlockNumber blkno,
76  BufferAccessStrategy bstrategy);
77 static void pgstat_gist_page(pgstattuple_type *stat,
78  Relation rel, BlockNumber blkno,
79  BufferAccessStrategy bstrategy);
80 static Datum pgstat_index(Relation rel, BlockNumber start,
81  pgstat_page pagefn, FunctionCallInfo fcinfo);
82 static void pgstat_index_page(pgstattuple_type *stat, Page page,
83  OffsetNumber minoff, OffsetNumber maxoff);
84 
85 /*
86  * build_pgstattuple_type -- build a pgstattuple_type tuple
87  */
88 static Datum
90 {
91 #define NCOLUMNS 9
92 #define NCHARS 32
93 
94  HeapTuple tuple;
95  char *values[NCOLUMNS];
96  char values_buf[NCOLUMNS][NCHARS];
97  int i;
98  double tuple_percent;
99  double dead_tuple_percent;
100  double free_percent; /* free/reusable space in % */
101  TupleDesc tupdesc;
102  AttInMetadata *attinmeta;
103 
104  /* Build a tuple descriptor for our result type */
105  if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
106  elog(ERROR, "return type must be a row type");
107 
108  /*
109  * Generate attribute metadata needed later to produce tuples from raw C
110  * strings
111  */
112  attinmeta = TupleDescGetAttInMetadata(tupdesc);
113 
114  if (stat->table_len == 0)
115  {
116  tuple_percent = 0.0;
117  dead_tuple_percent = 0.0;
118  free_percent = 0.0;
119  }
120  else
121  {
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;
125  }
126 
127  /*
128  * Prepare a values array for constructing the tuple. This should be an
129  * array of C strings which will be processed later by the appropriate
130  * "in" functions.
131  */
132  for (i = 0; i < NCOLUMNS; i++)
133  values[i] = values_buf[i];
134  i = 0;
135  snprintf(values[i++], NCHARS, INT64_FORMAT, stat->table_len);
136  snprintf(values[i++], NCHARS, INT64_FORMAT, stat->tuple_count);
137  snprintf(values[i++], NCHARS, INT64_FORMAT, stat->tuple_len);
138  snprintf(values[i++], NCHARS, "%.2f", tuple_percent);
139  snprintf(values[i++], NCHARS, INT64_FORMAT, stat->dead_tuple_count);
140  snprintf(values[i++], NCHARS, INT64_FORMAT, stat->dead_tuple_len);
141  snprintf(values[i++], NCHARS, "%.2f", dead_tuple_percent);
142  snprintf(values[i++], NCHARS, INT64_FORMAT, stat->free_space);
143  snprintf(values[i++], NCHARS, "%.2f", free_percent);
144 
145  /* build a tuple */
146  tuple = BuildTupleFromCStrings(attinmeta, values);
147 
148  /* make the tuple into a datum */
149  return HeapTupleGetDatum(tuple);
150 }
151 
152 /* ----------
153  * pgstattuple:
154  * returns live/dead tuples info
155  *
156  * C FUNCTION definition
157  * pgstattuple(text) returns pgstattuple_type
158  *
159  * The superuser() check here must be kept as the library might be upgraded
160  * without the extension being upgraded, meaning that in pre-1.5 installations
161  * these functions could be called by any user.
162  * ----------
163  */
164 
165 Datum
167 {
168  text *relname = PG_GETARG_TEXT_PP(0);
169  RangeVar *relrv;
170  Relation rel;
171 
172  if (!superuser())
173  ereport(ERROR,
174  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
175  (errmsg("must be superuser to use pgstattuple functions"))));
176 
177  /* open relation */
179  rel = relation_openrv(relrv, AccessShareLock);
180 
181  PG_RETURN_DATUM(pgstat_relation(rel, fcinfo));
182 }
183 
184 /*
185  * As of pgstattuple version 1.5, we no longer need to check if the user
186  * is a superuser because we REVOKE EXECUTE on the function from PUBLIC.
187  * Users can then grant access to it based on their policies.
188  *
189  * Otherwise identical to pgstattuple (above).
190  */
191 Datum
193 {
194  text *relname = PG_GETARG_TEXT_PP(0);
195  RangeVar *relrv;
196  Relation rel;
197 
198  /* open relation */
200  rel = relation_openrv(relrv, AccessShareLock);
201 
202  PG_RETURN_DATUM(pgstat_relation(rel, fcinfo));
203 }
204 
205 /* Must keep superuser() check, see above. */
206 Datum
208 {
209  Oid relid = PG_GETARG_OID(0);
210  Relation rel;
211 
212  if (!superuser())
213  ereport(ERROR,
214  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
215  (errmsg("must be superuser to use pgstattuple functions"))));
216 
217  /* open relation */
218  rel = relation_open(relid, AccessShareLock);
219 
220  PG_RETURN_DATUM(pgstat_relation(rel, fcinfo));
221 }
222 
223 /* Remove superuser() check for 1.5 version, see above */
224 Datum
226 {
227  Oid relid = PG_GETARG_OID(0);
228  Relation rel;
229 
230  /* open relation */
231  rel = relation_open(relid, AccessShareLock);
232 
233  PG_RETURN_DATUM(pgstat_relation(rel, fcinfo));
234 }
235 
236 /*
237  * pgstat_relation
238  */
239 static Datum
241 {
242  const char *err;
243 
244  /*
245  * Reject attempts to read non-local temporary relations; we would be
246  * likely to get wrong data since we have no visibility into the owning
247  * session's local buffers.
248  */
249  if (RELATION_IS_OTHER_TEMP(rel))
250  ereport(ERROR,
251  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
252  errmsg("cannot access temporary tables of other sessions")));
253 
254  switch (rel->rd_rel->relkind)
255  {
256  case RELKIND_RELATION:
257  case RELKIND_MATVIEW:
258  case RELKIND_TOASTVALUE:
259  case RELKIND_SEQUENCE:
260  return pgstat_heap(rel, fcinfo);
261  case RELKIND_INDEX:
262  switch (rel->rd_rel->relam)
263  {
264  case BTREE_AM_OID:
265  return pgstat_index(rel, BTREE_METAPAGE + 1,
266  pgstat_btree_page, fcinfo);
267  case HASH_AM_OID:
268  return pgstat_index(rel, HASH_METAPAGE + 1,
269  pgstat_hash_page, fcinfo);
270  case GIST_AM_OID:
271  return pgstat_index(rel, GIST_ROOT_BLKNO + 1,
272  pgstat_gist_page, fcinfo);
273  case GIN_AM_OID:
274  err = "gin index";
275  break;
276  case SPGIST_AM_OID:
277  err = "spgist index";
278  break;
279  case BRIN_AM_OID:
280  err = "brin index";
281  break;
282  default:
283  err = "unknown index";
284  break;
285  }
286  break;
287  case RELKIND_VIEW:
288  err = "view";
289  break;
291  err = "composite type";
292  break;
294  err = "foreign table";
295  break;
297  err = "partitioned table";
298  break;
299  default:
300  err = "unknown";
301  break;
302  }
303 
304  ereport(ERROR,
305  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
306  errmsg("\"%s\" (%s) is not supported",
307  RelationGetRelationName(rel), err)));
308  return 0; /* should not happen */
309 }
310 
311 /*
312  * pgstat_heap -- returns live/dead tuples info in a heap
313  */
314 static Datum
316 {
317  HeapScanDesc scan;
318  HeapTuple tuple;
319  BlockNumber nblocks;
320  BlockNumber block = 0; /* next block to count free space in */
321  BlockNumber tupblock;
322  Buffer buffer;
323  pgstattuple_type stat = {0};
324  SnapshotData SnapshotDirty;
325 
326  /* Disable syncscan because we assume we scan from block zero upwards */
327  scan = heap_beginscan_strat(rel, SnapshotAny, 0, NULL, true, false);
328  InitDirtySnapshot(SnapshotDirty);
329 
330  nblocks = scan->rs_nblocks; /* # blocks to be scanned */
331 
332  /* scan the relation */
333  while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
334  {
336 
337  /* must hold a buffer lock to call HeapTupleSatisfiesVisibility */
339 
340  if (HeapTupleSatisfiesVisibility(tuple, &SnapshotDirty, scan->rs_cbuf))
341  {
342  stat.tuple_len += tuple->t_len;
343  stat.tuple_count++;
344  }
345  else
346  {
347  stat.dead_tuple_len += tuple->t_len;
348  stat.dead_tuple_count++;
349  }
350 
352 
353  /*
354  * To avoid physically reading the table twice, try to do the
355  * free-space scan in parallel with the heap scan. However,
356  * heap_getnext may find no tuples on a given page, so we cannot
357  * simply examine the pages returned by the heap scan.
358  */
359  tupblock = ItemPointerGetBlockNumber(&tuple->t_self);
360 
361  while (block <= tupblock)
362  {
364 
365  buffer = ReadBufferExtended(rel, MAIN_FORKNUM, block,
366  RBM_NORMAL, scan->rs_strategy);
367  LockBuffer(buffer, BUFFER_LOCK_SHARE);
369  UnlockReleaseBuffer(buffer);
370  block++;
371  }
372  }
373 
374  while (block < nblocks)
375  {
377 
378  buffer = ReadBufferExtended(rel, MAIN_FORKNUM, block,
379  RBM_NORMAL, scan->rs_strategy);
380  LockBuffer(buffer, BUFFER_LOCK_SHARE);
382  UnlockReleaseBuffer(buffer);
383  block++;
384  }
385 
386  heap_endscan(scan);
388 
389  stat.table_len = (uint64) nblocks *BLCKSZ;
390 
391  return build_pgstattuple_type(&stat, fcinfo);
392 }
393 
394 /*
395  * pgstat_btree_page -- check tuples in a btree page
396  */
397 static void
399  BufferAccessStrategy bstrategy)
400 {
401  Buffer buf;
402  Page page;
403 
404  buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy);
405  LockBuffer(buf, BT_READ);
406  page = BufferGetPage(buf);
407 
408  /* Page is valid, see what to do with it */
409  if (PageIsNew(page))
410  {
411  /* fully empty page */
412  stat->free_space += BLCKSZ;
413  }
414  else
415  {
416  BTPageOpaque opaque;
417 
418  opaque = (BTPageOpaque) PageGetSpecialPointer(page);
419  if (opaque->btpo_flags & (BTP_DELETED | BTP_HALF_DEAD))
420  {
421  /* recyclable page */
422  stat->free_space += BLCKSZ;
423  }
424  else if (P_ISLEAF(opaque))
425  {
426  pgstat_index_page(stat, page, P_FIRSTDATAKEY(opaque),
427  PageGetMaxOffsetNumber(page));
428  }
429  else
430  {
431  /* root or node */
432  }
433  }
434 
435  _bt_relbuf(rel, buf);
436 }
437 
438 /*
439  * pgstat_hash_page -- check tuples in a hash page
440  */
441 static void
443  BufferAccessStrategy bstrategy)
444 {
445  Buffer buf;
446  Page page;
447 
448  buf = _hash_getbuf_with_strategy(rel, blkno, HASH_READ, 0, bstrategy);
449  page = BufferGetPage(buf);
450 
451  if (PageGetSpecialSize(page) == MAXALIGN(sizeof(HashPageOpaqueData)))
452  {
453  HashPageOpaque opaque;
454 
455  opaque = (HashPageOpaque) PageGetSpecialPointer(page);
456  switch (opaque->hasho_flag & LH_PAGE_TYPE)
457  {
458  case LH_UNUSED_PAGE:
459  stat->free_space += BLCKSZ;
460  break;
461  case LH_BUCKET_PAGE:
462  case LH_OVERFLOW_PAGE:
464  PageGetMaxOffsetNumber(page));
465  break;
466  case LH_BITMAP_PAGE:
467  case LH_META_PAGE:
468  default:
469  break;
470  }
471  }
472  else
473  {
474  /* maybe corrupted */
475  }
476 
477  _hash_relbuf(rel, buf);
478 }
479 
480 /*
481  * pgstat_gist_page -- check tuples in a gist page
482  */
483 static void
485  BufferAccessStrategy bstrategy)
486 {
487  Buffer buf;
488  Page page;
489 
490  buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy);
491  LockBuffer(buf, GIST_SHARE);
492  gistcheckpage(rel, buf);
493  page = BufferGetPage(buf);
494 
495  if (GistPageIsLeaf(page))
496  {
498  PageGetMaxOffsetNumber(page));
499  }
500  else
501  {
502  /* root or node */
503  }
504 
505  UnlockReleaseBuffer(buf);
506 }
507 
508 /*
509  * pgstat_index -- returns live/dead tuples info in a generic index
510  */
511 static Datum
513  FunctionCallInfo fcinfo)
514 {
515  BlockNumber nblocks;
516  BlockNumber blkno;
517  BufferAccessStrategy bstrategy;
518  pgstattuple_type stat = {0};
519 
520  /* prepare access strategy for this index */
521  bstrategy = GetAccessStrategy(BAS_BULKREAD);
522 
523  blkno = start;
524  for (;;)
525  {
526  /* Get the current relation length */
528  nblocks = RelationGetNumberOfBlocks(rel);
530 
531  /* Quit if we've scanned the whole relation */
532  if (blkno >= nblocks)
533  {
534  stat.table_len = (uint64) nblocks *BLCKSZ;
535 
536  break;
537  }
538 
539  for (; blkno < nblocks; blkno++)
540  {
542 
543  pagefn(&stat, rel, blkno, bstrategy);
544  }
545  }
546 
548 
549  return build_pgstattuple_type(&stat, fcinfo);
550 }
551 
552 /*
553  * pgstat_index_page -- for generic index page
554  */
555 static void
557  OffsetNumber minoff, OffsetNumber maxoff)
558 {
559  OffsetNumber i;
560 
561  stat->free_space += PageGetFreeSpace(page);
562 
563  for (i = minoff; i <= maxoff; i = OffsetNumberNext(i))
564  {
565  ItemId itemid = PageGetItemId(page, i);
566 
567  if (ItemIdIsDead(itemid))
568  {
569  stat->dead_tuple_count++;
570  stat->dead_tuple_len += ItemIdGetLength(itemid);
571  }
572  else
573  {
574  stat->tuple_count++;
575  stat->tuple_len += ItemIdGetLength(itemid);
576  }
577  }
578 }
BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype)
Definition: freelist.c:525
static void pgstat_hash_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno, BufferAccessStrategy bstrategy)
Definition: pgstattuple.c:442
Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
Definition: heapam.c:1192
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:87
static void pgstat_btree_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno, BufferAccessStrategy bstrategy)
Definition: pgstattuple.c:398
PG_FUNCTION_INFO_V1(pgstattuple)
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:211
#define LH_BITMAP_PAGE
Definition: hash.h:55
void heap_endscan(HeapScanDesc scan)
Definition: heapam.c:1578
PG_MODULE_MAGIC
Definition: pgstattuple.c:41
#define BRIN_AM_OID
Definition: pg_am.h:85
#define LH_META_PAGE
Definition: hash.h:56
#define ExclusiveLock
Definition: lockdefs.h:44
Buffer _hash_getbuf_with_strategy(Relation rel, BlockNumber blkno, int access, int flags, BufferAccessStrategy bstrategy)
Definition: hashpage.c:247
#define P_FIRSTDATAKEY(opaque)
Definition: nbtree.h:205
struct BufferAccessStrategyData * BufferAccessStrategy
Definition: buf.h:44
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition: bufmgr.c:640
#define NCOLUMNS
uint64 dead_tuple_count
Definition: pgstattuple.c:59
#define BTP_HALF_DEAD
Definition: nbtree.h:74
#define BTREE_AM_OID
Definition: pg_am.h:70
#define RELKIND_MATVIEW
Definition: pg_class.h:165
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1260
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
uint32 BlockNumber
Definition: block.h:31
RangeVar * makeRangeVarFromNameList(List *names)
Definition: namespace.c:2980
#define BTP_DELETED
Definition: nbtree.h:72
Form_pg_class rd_rel
Definition: rel.h:114
unsigned int Oid
Definition: postgres_ext.h:31
#define ItemIdIsDead(itemId)
Definition: itemid.h:112
#define HASH_AM_OID
Definition: pg_am.h:73
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:354
BTPageOpaqueData * BTPageOpaque
Definition: nbtree.h:67
#define RELKIND_COMPOSITE_TYPE
Definition: pg_class.h:166
Size PageGetFreeSpace(Page page)
Definition: bufpage.c:582
#define HeapTupleSatisfiesVisibility(tuple, snapshot, buffer)
Definition: tqual.h:45
#define GIN_AM_OID
Definition: pg_am.h:79
HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
Definition: execTuples.c:1115
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define LH_UNUSED_PAGE
Definition: hash.h:52
uint16 OffsetNumber
Definition: off.h:24
#define LH_PAGE_TYPE
Definition: hash.h:62
#define HASH_READ
Definition: hash.h:283
uint64 dead_tuple_len
Definition: pgstattuple.c:60
#define BT_READ
Definition: nbtree.h:238
struct RelationData * Relation
Definition: relcache.h:21
#define ItemIdGetLength(itemId)
Definition: itemid.h:58
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
#define ERROR
Definition: elog.h:43
Size PageGetHeapFreeSpace(Page page)
Definition: bufpage.c:666
#define InitDirtySnapshot(snapshotdata)
Definition: tqual.h:100
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
static char * buf
Definition: pg_test_fsync.c:66
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define FirstOffsetNumber
Definition: off.h:27
#define RelationGetRelationName(relation)
Definition: rel.h:437
#define RELKIND_FOREIGN_TABLE
Definition: pg_class.h:167
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define ereport(elevel, rest)
Definition: elog.h:122
#define BTREE_METAPAGE
Definition: nbtree.h:109
List * textToQualifiedNameList(text *textval)
Definition: varlena.c:3189
#define GistPageIsLeaf(page)
Definition: gist.h:132
static Datum pgstat_heap(Relation rel, FunctionCallInfo fcinfo)
Definition: pgstattuple.c:315
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:232
void LockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:332
#define RELKIND_PARTITIONED_TABLE
Definition: pg_class.h:168
#define RELKIND_TOASTVALUE
Definition: pg_class.h:163
Datum pgstattuple(PG_FUNCTION_ARGS)
Definition: pgstattuple.c:166
void UnlockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:382
#define NCHARS
#define HASH_METAPAGE
Definition: hash.h:159
uintptr_t Datum
Definition: postgres.h:372
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:313
#define SnapshotAny
Definition: tqual.h:28
#define LH_OVERFLOW_PAGE
Definition: hash.h:53
static Datum pgstat_index(Relation rel, BlockNumber start, pgstat_page pagefn, FunctionCallInfo fcinfo)
Definition: pgstattuple.c:512
BlockNumber rs_nblocks
Definition: relscan.h:59
AttInMetadata * TupleDescGetAttInMetadata(TupleDesc tupdesc)
Definition: execTuples.c:1068
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
HeapTuple heap_getnext(HeapScanDesc scan, ScanDirection direction)
Definition: heapam.c:1794
BufferAccessStrategy rs_strategy
Definition: relscan.h:63
#define RelationGetNumberOfBlocks(reln)
Definition: bufmgr.h:199
Datum pgstattuplebyid_v1_5(PG_FUNCTION_ARGS)
Definition: pgstattuple.c:225
void(* pgstat_page)(pgstattuple_type *, Relation, BlockNumber, BufferAccessStrategy)
Definition: pgstattuple.c:64
void _bt_relbuf(Relation rel, Buffer buf)
Definition: nbtpage.c:720
void _hash_relbuf(Relation rel, Buffer buf)
Definition: hashpage.c:274
HeapScanDesc heap_beginscan_strat(Relation relation, Snapshot snapshot, int nkeys, ScanKey key, bool allow_strat, bool allow_sync)
Definition: heapam.c:1409
#define LH_BUCKET_PAGE
Definition: hash.h:54
Buffer rs_cbuf
Definition: relscan.h:70
#define NULL
Definition: c.h:229
#define GIST_AM_OID
Definition: pg_am.h:76
#define RELATION_IS_OTHER_TEMP(relation)
Definition: rel.h:534
static void pgstat_gist_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno, BufferAccessStrategy bstrategy)
Definition: pgstattuple.c:484
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:211
void gistcheckpage(Relation rel, Buffer buf)
Definition: gistutil.c:723
#define OffsetNumberNext(offsetNumber)
Definition: off.h:53
#define PageGetSpecialPointer(page)
Definition: bufpage.h:323
HashPageOpaqueData * HashPageOpaque
Definition: hash.h:85
struct pgstattuple_type pgstattuple_type
#define MAXALIGN(LEN)
Definition: c.h:588
#define GIST_SHARE
Definition: gist_private.h:43
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:222
#define PageGetSpecialSize(page)
Definition: bufpage.h:297
static void pgstat_index_page(pgstattuple_type *stat, Page page, OffsetNumber minoff, OffsetNumber maxoff)
Definition: pgstattuple.c:556
#define INT64_FORMAT
Definition: c.h:315
uint16 hasho_flag
Definition: hash.h:81
static Datum values[MAXATTR]
Definition: bootstrap.c:163
#define PageIsNew(page)
Definition: bufpage.h:226
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define RELKIND_VIEW
Definition: pg_class.h:164
int i
#define GIST_ROOT_BLKNO
Definition: gist_private.h:249
#define RELKIND_INDEX
Definition: pg_class.h:161
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:88
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1114
#define SPGIST_AM_OID
Definition: pg_am.h:82
Definition: c.h:439
#define PG_FUNCTION_ARGS
Definition: fmgr.h:158
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:97
static Datum pgstat_relation(Relation rel, FunctionCallInfo fcinfo)
Definition: pgstattuple.c:240
#define elog
Definition: elog.h:219
#define ItemPointerGetBlockNumber(pointer)
Definition: itemptr.h:75
static Datum build_pgstattuple_type(pgstattuple_type *stat, FunctionCallInfo fcinfo)
Definition: pgstattuple.c:89
Datum pgstattuplebyid(PG_FUNCTION_ARGS)
Definition: pgstattuple.c:207
#define RELKIND_RELATION
Definition: pg_class.h:160
uint16 btpo_flags
Definition: nbtree.h:63
#define RELKIND_SEQUENCE
Definition: pg_class.h:162
int Buffer
Definition: buf.h:23
uint64 tuple_count
Definition: pgstattuple.c:57
Datum pgstattuple_v1_5(PG_FUNCTION_ARGS)
Definition: pgstattuple.c:192
Pointer Page
Definition: bufpage.h:74
#define P_ISLEAF(opaque)
Definition: nbtree.h:176