PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pgstatindex.c
Go to the documentation of this file.
1 /*
2  * contrib/pgstattuple/pgstatindex.c
3  *
4  *
5  * pgstatindex
6  *
7  * Copyright (c) 2006 Satoshi Nagayasu <nagayasus@nttdata.co.jp>
8  *
9  * Permission to use, copy, modify, and distribute this software and
10  * its documentation for any purpose, without fee, and without a
11  * written agreement is hereby granted, provided that the above
12  * copyright notice and this paragraph and the following two
13  * paragraphs appear in all copies.
14  *
15  * IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT,
16  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
17  * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
18  * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED
19  * OF THE POSSIBILITY OF SUCH DAMAGE.
20  *
21  * THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS
24  * IS" BASIS, AND THE AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE,
25  * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
26  */
27 
28 #include "postgres.h"
29 
30 #include "access/gin_private.h"
31 #include "access/heapam.h"
32 #include "access/hash.h"
33 #include "access/htup_details.h"
34 #include "access/nbtree.h"
35 #include "catalog/namespace.h"
36 #include "catalog/pg_am.h"
37 #include "funcapi.h"
38 #include "miscadmin.h"
39 #include "storage/bufmgr.h"
40 #include "storage/lmgr.h"
41 #include "utils/builtins.h"
42 #include "utils/rel.h"
43 #include "utils/varlena.h"
44 
45 
46 /*
47  * Because of backward-compatibility issue, we have decided to have
48  * two types of interfaces, with regclass-type input arg and text-type
49  * input arg, for each function.
50  *
51  * Those functions which have text-type input arg will be deprecated
52  * in the future release.
53  */
60 
66 
68 
69 #define IS_INDEX(r) ((r)->rd_rel->relkind == RELKIND_INDEX)
70 #define IS_BTREE(r) ((r)->rd_rel->relam == BTREE_AM_OID)
71 #define IS_GIN(r) ((r)->rd_rel->relam == GIN_AM_OID)
72 #define IS_HASH(r) ((r)->rd_rel->relam == HASH_AM_OID)
73 
74 /* ------------------------------------------------
75  * A structure for a whole btree index statistics
76  * used by pgstatindex().
77  * ------------------------------------------------
78  */
79 typedef struct BTIndexStat
80 {
84 
86  uint64 leaf_pages;
87  uint64 empty_pages;
88  uint64 deleted_pages;
89 
90  uint64 max_avail;
91  uint64 free_space;
92 
93  uint64 fragments;
94 } BTIndexStat;
95 
96 /* ------------------------------------------------
97  * A structure for a whole GIN index statistics
98  * used by pgstatginindex().
99  * ------------------------------------------------
100  */
101 typedef struct GinIndexStat
102 {
104 
107 } GinIndexStat;
108 
109 /* ------------------------------------------------
110  * A structure for a whole HASH index statistics
111  * used by pgstathashindex().
112  * ------------------------------------------------
113  */
114 typedef struct HashIndexStat
115 {
118 
123 
124  int64 live_items;
125  int64 dead_items;
126  uint64 free_space;
127 } HashIndexStat;
128 
129 static Datum pgstatindex_impl(Relation rel, FunctionCallInfo fcinfo);
130 static void GetHashPageStats(Page page, HashIndexStat *stats);
131 
132 
133 /* ------------------------------------------------------
134  * pgstatindex()
135  *
136  * Usage: SELECT * FROM pgstatindex('t1_pkey');
137  *
138  * The superuser() check here must be kept as the library might be upgraded
139  * without the extension being upgraded, meaning that in pre-1.5 installations
140  * these functions could be called by any user.
141  * ------------------------------------------------------
142  */
143 Datum
145 {
146  text *relname = PG_GETARG_TEXT_P(0);
147  Relation rel;
148  RangeVar *relrv;
149 
150  if (!superuser())
151  ereport(ERROR,
152  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
153  (errmsg("must be superuser to use pgstattuple functions"))));
154 
156  rel = relation_openrv(relrv, AccessShareLock);
157 
158  PG_RETURN_DATUM(pgstatindex_impl(rel, fcinfo));
159 }
160 
161 /*
162  * As of pgstattuple version 1.5, we no longer need to check if the user
163  * is a superuser because we REVOKE EXECUTE on the function from PUBLIC.
164  * Users can then grant access to it based on their policies.
165  *
166  * Otherwise identical to pgstatindex (above).
167  */
168 Datum
170 {
171  text *relname = PG_GETARG_TEXT_P(0);
172  Relation rel;
173  RangeVar *relrv;
174 
176  rel = relation_openrv(relrv, AccessShareLock);
177 
178  PG_RETURN_DATUM(pgstatindex_impl(rel, fcinfo));
179 }
180 
181 /*
182  * The superuser() check here must be kept as the library might be upgraded
183  * without the extension being upgraded, meaning that in pre-1.5 installations
184  * these functions could be called by any user.
185  */
186 Datum
188 {
189  Oid relid = PG_GETARG_OID(0);
190  Relation rel;
191 
192  if (!superuser())
193  ereport(ERROR,
194  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
195  (errmsg("must be superuser to use pgstattuple functions"))));
196 
197  rel = relation_open(relid, AccessShareLock);
198 
199  PG_RETURN_DATUM(pgstatindex_impl(rel, fcinfo));
200 }
201 
202 /* No need for superuser checks in v1.5, see above */
203 Datum
205 {
206  Oid relid = PG_GETARG_OID(0);
207  Relation rel;
208 
209  rel = relation_open(relid, AccessShareLock);
210 
211  PG_RETURN_DATUM(pgstatindex_impl(rel, fcinfo));
212 }
213 
214 static Datum
216 {
217  Datum result;
218  BlockNumber nblocks;
219  BlockNumber blkno;
220  BTIndexStat indexStat;
222 
223  if (!IS_INDEX(rel) || !IS_BTREE(rel))
224  elog(ERROR, "relation \"%s\" is not a btree index",
226 
227  /*
228  * Reject attempts to read non-local temporary relations; we would be
229  * likely to get wrong data since we have no visibility into the owning
230  * session's local buffers.
231  */
232  if (RELATION_IS_OTHER_TEMP(rel))
233  ereport(ERROR,
234  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
235  errmsg("cannot access temporary tables of other sessions")));
236 
237  /*
238  * Read metapage
239  */
240  {
241  Buffer buffer = ReadBufferExtended(rel, MAIN_FORKNUM, 0, RBM_NORMAL, bstrategy);
242  Page page = BufferGetPage(buffer);
243  BTMetaPageData *metad = BTPageGetMeta(page);
244 
245  indexStat.version = metad->btm_version;
246  indexStat.level = metad->btm_level;
247  indexStat.root_blkno = metad->btm_root;
248 
249  ReleaseBuffer(buffer);
250  }
251 
252  /* -- init counters -- */
253  indexStat.internal_pages = 0;
254  indexStat.leaf_pages = 0;
255  indexStat.empty_pages = 0;
256  indexStat.deleted_pages = 0;
257 
258  indexStat.max_avail = 0;
259  indexStat.free_space = 0;
260 
261  indexStat.fragments = 0;
262 
263  /*
264  * Scan all blocks except the metapage
265  */
266  nblocks = RelationGetNumberOfBlocks(rel);
267 
268  for (blkno = 1; blkno < nblocks; blkno++)
269  {
270  Buffer buffer;
271  Page page;
272  BTPageOpaque opaque;
273 
275 
276  /* Read and lock buffer */
277  buffer = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy);
278  LockBuffer(buffer, BUFFER_LOCK_SHARE);
279 
280  page = BufferGetPage(buffer);
281  opaque = (BTPageOpaque) PageGetSpecialPointer(page);
282 
283  /* Determine page type, and update totals */
284 
285  if (P_ISDELETED(opaque))
286  indexStat.deleted_pages++;
287  else if (P_IGNORE(opaque))
288  indexStat.empty_pages++; /* this is the "half dead" state */
289  else if (P_ISLEAF(opaque))
290  {
291  int max_avail;
292 
293  max_avail = BLCKSZ - (BLCKSZ - ((PageHeader) page)->pd_special + SizeOfPageHeaderData);
294  indexStat.max_avail += max_avail;
295  indexStat.free_space += PageGetFreeSpace(page);
296 
297  indexStat.leaf_pages++;
298 
299  /*
300  * If the next leaf is on an earlier block, it means a
301  * fragmentation.
302  */
303  if (opaque->btpo_next != P_NONE && opaque->btpo_next < blkno)
304  indexStat.fragments++;
305  }
306  else
307  indexStat.internal_pages++;
308 
309  /* Unlock and release buffer */
311  ReleaseBuffer(buffer);
312  }
313 
315 
316  /*----------------------------
317  * Build a result tuple
318  *----------------------------
319  */
320  {
322  int j;
323  char *values[10];
324  HeapTuple tuple;
325 
326  /* Build a tuple descriptor for our result type */
327  if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
328  elog(ERROR, "return type must be a row type");
329 
330  j = 0;
331  values[j++] = psprintf("%d", indexStat.version);
332  values[j++] = psprintf("%d", indexStat.level);
333  values[j++] = psprintf(INT64_FORMAT,
334  (1 + /* include the metapage in index_size */
335  indexStat.leaf_pages +
336  indexStat.internal_pages +
337  indexStat.deleted_pages +
338  indexStat.empty_pages) * BLCKSZ);
339  values[j++] = psprintf("%u", indexStat.root_blkno);
340  values[j++] = psprintf(INT64_FORMAT, indexStat.internal_pages);
341  values[j++] = psprintf(INT64_FORMAT, indexStat.leaf_pages);
342  values[j++] = psprintf(INT64_FORMAT, indexStat.empty_pages);
343  values[j++] = psprintf(INT64_FORMAT, indexStat.deleted_pages);
344  if (indexStat.max_avail > 0)
345  values[j++] = psprintf("%.2f",
346  100.0 - (double) indexStat.free_space / (double) indexStat.max_avail * 100.0);
347  else
348  values[j++] = pstrdup("NaN");
349  if (indexStat.leaf_pages > 0)
350  values[j++] = psprintf("%.2f",
351  (double) indexStat.fragments / (double) indexStat.leaf_pages * 100.0);
352  else
353  values[j++] = pstrdup("NaN");
354 
356  values);
357 
358  result = HeapTupleGetDatum(tuple);
359  }
360 
361  return result;
362 }
363 
364 /* --------------------------------------------------------
365  * pg_relpages()
366  *
367  * Get the number of pages of the table/index.
368  *
369  * Usage: SELECT pg_relpages('t1');
370  * SELECT pg_relpages('t1_pkey');
371  *
372  * Must keep superuser() check, see above.
373  * --------------------------------------------------------
374  */
375 Datum
377 {
378  text *relname = PG_GETARG_TEXT_P(0);
379  int64 relpages;
380  Relation rel;
381  RangeVar *relrv;
382 
383  if (!superuser())
384  ereport(ERROR,
385  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
386  (errmsg("must be superuser to use pgstattuple functions"))));
387 
389  rel = relation_openrv(relrv, AccessShareLock);
390 
391  /* note: this will work OK on non-local temp tables */
392 
393  relpages = RelationGetNumberOfBlocks(rel);
394 
396 
397  PG_RETURN_INT64(relpages);
398 }
399 
400 /* No need for superuser checks in v1.5, see above */
401 Datum
403 {
404  text *relname = PG_GETARG_TEXT_P(0);
405  int64 relpages;
406  Relation rel;
407  RangeVar *relrv;
408 
410  rel = relation_openrv(relrv, AccessShareLock);
411 
412  /* note: this will work OK on non-local temp tables */
413 
414  relpages = RelationGetNumberOfBlocks(rel);
415 
417 
418  PG_RETURN_INT64(relpages);
419 }
420 
421 /* Must keep superuser() check, see above. */
422 Datum
424 {
425  Oid relid = PG_GETARG_OID(0);
426  int64 relpages;
427  Relation rel;
428 
429  if (!superuser())
430  ereport(ERROR,
431  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
432  (errmsg("must be superuser to use pgstattuple functions"))));
433 
434  rel = relation_open(relid, AccessShareLock);
435 
436  /* note: this will work OK on non-local temp tables */
437 
438  relpages = RelationGetNumberOfBlocks(rel);
439 
441 
442  PG_RETURN_INT64(relpages);
443 }
444 
445 /* No need for superuser checks in v1.5, see above */
446 Datum
448 {
449  Oid relid = PG_GETARG_OID(0);
450  int64 relpages;
451  Relation rel;
452 
453  rel = relation_open(relid, AccessShareLock);
454 
455  /* note: this will work OK on non-local temp tables */
456 
457  relpages = RelationGetNumberOfBlocks(rel);
458 
460 
461  PG_RETURN_INT64(relpages);
462 }
463 
464 /* ------------------------------------------------------
465  * pgstatginindex()
466  *
467  * Usage: SELECT * FROM pgstatginindex('ginindex');
468  *
469  * Must keep superuser() check, see above.
470  * ------------------------------------------------------
471  */
472 Datum
474 {
475  Oid relid = PG_GETARG_OID(0);
476 
477  if (!superuser())
478  ereport(ERROR,
479  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
480  (errmsg("must be superuser to use pgstattuple functions"))));
481 
483 }
484 
485 /* No need for superuser checks in v1.5, see above */
486 Datum
488 {
489  Oid relid = PG_GETARG_OID(0);
490 
492 }
493 
494 Datum
496 {
497  Relation rel;
498  Buffer buffer;
499  Page page;
500  GinMetaPageData *metadata;
501  GinIndexStat stats;
502  HeapTuple tuple;
504  Datum values[3];
505  bool nulls[3] = {false, false, false};
506  Datum result;
507 
508  rel = relation_open(relid, AccessShareLock);
509 
510  if (!IS_INDEX(rel) || !IS_GIN(rel))
511  elog(ERROR, "relation \"%s\" is not a GIN index",
513 
514  /*
515  * Reject attempts to read non-local temporary relations; we would be
516  * likely to get wrong data since we have no visibility into the owning
517  * session's local buffers.
518  */
519  if (RELATION_IS_OTHER_TEMP(rel))
520  ereport(ERROR,
521  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
522  errmsg("cannot access temporary indexes of other sessions")));
523 
524  /*
525  * Read metapage
526  */
527  buffer = ReadBuffer(rel, GIN_METAPAGE_BLKNO);
528  LockBuffer(buffer, GIN_SHARE);
529  page = BufferGetPage(buffer);
530  metadata = GinPageGetMeta(page);
531 
532  stats.version = metadata->ginVersion;
533  stats.pending_pages = metadata->nPendingPages;
534  stats.pending_tuples = metadata->nPendingHeapTuples;
535 
536  UnlockReleaseBuffer(buffer);
538 
539  /*
540  * Build a tuple descriptor for our result type
541  */
542  if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
543  elog(ERROR, "return type must be a row type");
544 
545  values[0] = Int32GetDatum(stats.version);
546  values[1] = UInt32GetDatum(stats.pending_pages);
547  values[2] = Int64GetDatum(stats.pending_tuples);
548 
549  /*
550  * Build and return the tuple
551  */
552  tuple = heap_form_tuple(tupleDesc, values, nulls);
553  result = HeapTupleGetDatum(tuple);
554 
555  return (result);
556 }
557 
558 /* ------------------------------------------------------
559  * pgstathashindex()
560  *
561  * Usage: SELECT * FROM pgstathashindex('hashindex');
562  * ------------------------------------------------------
563  */
564 Datum
566 {
567  Oid relid = PG_GETARG_OID(0);
568  BlockNumber nblocks;
569  BlockNumber blkno;
570  Relation rel;
571  HashIndexStat stats;
572  BufferAccessStrategy bstrategy;
573  HeapTuple tuple;
575  Datum values[8];
576  bool nulls[8];
577  Buffer metabuf;
578  HashMetaPage metap;
579  float8 free_percent;
580  uint64 total_space;
581 
582  rel = index_open(relid, AccessShareLock);
583 
584  if (!IS_HASH(rel))
585  elog(ERROR, "relation \"%s\" is not a HASH index",
587 
588  /*
589  * Reject attempts to read non-local temporary relations; we would be
590  * likely to get wrong data since we have no visibility into the owning
591  * session's local buffers.
592  */
593  if (RELATION_IS_OTHER_TEMP(rel))
594  ereport(ERROR,
595  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
596  errmsg("cannot access temporary indexes of other sessions")));
597 
598  /* Get the information we need from the metapage. */
599  memset(&stats, 0, sizeof(stats));
601  metap = HashPageGetMeta(BufferGetPage(metabuf));
602  stats.version = metap->hashm_version;
603  stats.space_per_page = metap->hashm_bsize;
604  _hash_relbuf(rel, metabuf);
605 
606  /* Get the current relation length */
607  nblocks = RelationGetNumberOfBlocks(rel);
608 
609  /* prepare access strategy for this index */
610  bstrategy = GetAccessStrategy(BAS_BULKREAD);
611 
612  /* Start from blkno 1 as 0th block is metapage */
613  for (blkno = 1; blkno < nblocks; blkno++)
614  {
615  Buffer buf;
616  Page page;
617  HashPageOpaque opaque;
618 
620 
621  buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL,
622  bstrategy);
624  page = (Page) BufferGetPage(buf);
625 
626  if (PageIsNew(page))
627  stats.zero_pages++;
628  else if (PageGetSpecialSize(page) !=
629  MAXALIGN(sizeof(HashPageOpaqueData)))
630  ereport(ERROR,
631  (errcode(ERRCODE_INDEX_CORRUPTED),
632  errmsg("index \"%s\" contains corrupted page at block %u",
634  BufferGetBlockNumber(buf))));
635  else
636  {
637  opaque = (HashPageOpaque) PageGetSpecialPointer(page);
638  if (opaque->hasho_flag & LH_BUCKET_PAGE)
639  {
640  stats.bucket_pages++;
641  GetHashPageStats(page, &stats);
642  }
643  else if (opaque->hasho_flag & LH_OVERFLOW_PAGE)
644  {
645  stats.overflow_pages++;
646  GetHashPageStats(page, &stats);
647  }
648  else if (opaque->hasho_flag & LH_BITMAP_PAGE)
649  stats.bitmap_pages++;
650  else
651  ereport(ERROR,
652  (errcode(ERRCODE_INDEX_CORRUPTED),
653  errmsg("unexpected page type 0x%04X in HASH index \"%s\" block %u",
654  opaque->hasho_flag, RelationGetRelationName(rel),
655  BufferGetBlockNumber(buf))));
656  }
657  UnlockReleaseBuffer(buf);
658  }
659 
660  /* Done accessing the index */
662 
663  /* Count zero pages as free space. */
664  stats.free_space += stats.zero_pages * stats.space_per_page;
665 
666  /*
667  * Total space available for tuples excludes the metapage and the bitmap
668  * pages.
669  */
670  total_space = (nblocks - (stats.bitmap_pages + 1)) * stats.space_per_page;
671 
672  if (total_space == 0)
673  free_percent = 0.0;
674  else
675  free_percent = 100.0 * stats.free_space / total_space;
676 
677  /*
678  * Build a tuple descriptor for our result type
679  */
680  if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
681  elog(ERROR, "return type must be a row type");
682 
683  tupleDesc = BlessTupleDesc(tupleDesc);
684 
685  /*
686  * Build and return the tuple
687  */
688  MemSet(nulls, 0, sizeof(nulls));
689  values[0] = Int32GetDatum(stats.version);
690  values[1] = Int64GetDatum((int64) stats.bucket_pages);
691  values[2] = Int64GetDatum((int64) stats.overflow_pages);
692  values[3] = Int64GetDatum((int64) stats.bitmap_pages);
693  values[4] = Int64GetDatum((int64) stats.zero_pages);
694  values[5] = Int64GetDatum(stats.live_items);
695  values[6] = Int64GetDatum(stats.dead_items);
696  values[7] = Float8GetDatum(free_percent);
697  tuple = heap_form_tuple(tupleDesc, values, nulls);
698 
700 }
701 
702 /* -------------------------------------------------
703  * GetHashPageStatis()
704  *
705  * Collect statistics of single hash page
706  * -------------------------------------------------
707  */
708 static void
710 {
711  OffsetNumber maxoff = PageGetMaxOffsetNumber(page);
712  int off;
713 
714  /* count live and dead tuples, and free space */
715  for (off = FirstOffsetNumber; off <= maxoff; off++)
716  {
717  ItemId id = PageGetItemId(page, off);
718 
719  if (!ItemIdIsDead(id))
720  stats->live_items++;
721  else
722  stats->dead_items++;
723  }
724  stats->free_space += PageGetExactFreeSpace(page);
725 }
uint64 empty_pages
Definition: pgstatindex.c:87
BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype)
Definition: freelist.c:525
Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
Definition: heapam.c:1195
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:87
BlockNumber btpo_next
Definition: nbtree.h:57
BlockNumber overflow_pages
Definition: pgstatindex.c:120
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:211
#define LH_BITMAP_PAGE
Definition: hash.h:55
#define P_IGNORE(opaque)
Definition: nbtree.h:181
uint64 fragments
Definition: pgstatindex.c:93
int64 pending_tuples
Definition: pgstatindex.c:106
uint32 version
Definition: pgstatindex.c:81
uint32 btm_version
Definition: nbtree.h:99
BlockNumber root_blkno
Definition: pgstatindex.c:83
#define LH_META_PAGE
Definition: hash.h:56
#define PG_RETURN_INT64(x)
Definition: fmgr.h:311
BlockNumber bitmap_pages
Definition: pgstatindex.c:121
Datum pgstatginindex_internal(Oid relid, FunctionCallInfo fcinfo)
Definition: pgstatindex.c:495
char * pstrdup(const char *in)
Definition: mcxt.c:1165
struct BTIndexStat BTIndexStat
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition: bufmgr.c:640
Datum pg_relpagesbyid_v1_5(PG_FUNCTION_ARGS)
Definition: pgstatindex.c:447
#define P_NONE
Definition: nbtree.h:169
#define AccessShareLock
Definition: lockdefs.h:36
Datum pgstatginindex_v1_5(PG_FUNCTION_ARGS)
Definition: pgstatindex.c:487
int errcode(int sqlerrcode)
Definition: elog.c:575
BlockNumber zero_pages
Definition: pgstatindex.c:122
bool superuser(void)
Definition: superuser.c:47
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1263
#define MemSet(start, val, len)
Definition: c.h:852
uint32 BlockNumber
Definition: block.h:31
Datum pgstathashindex(PG_FUNCTION_ARGS)
Definition: pgstatindex.c:565
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3292
#define GIN_METAPAGE_BLKNO
Definition: ginblock.h:50
uint64 free_space
Definition: pgstatindex.c:126
RangeVar * makeRangeVarFromNameList(List *names)
Definition: namespace.c:2857
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
Datum pgstatindex_v1_5(PG_FUNCTION_ARGS)
Definition: pgstatindex.c:169
#define IS_INDEX(r)
Definition: pgstatindex.c:69
Buffer _hash_getbuf(Relation rel, BlockNumber blkno, int access, int flags)
Definition: hashpage.c:79
#define SizeOfPageHeaderData
Definition: bufpage.h:213
unsigned int Oid
Definition: postgres_ext.h:31
#define ItemIdIsDead(itemId)
Definition: itemid.h:112
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:354
BTPageOpaqueData * BTPageOpaque
Definition: nbtree.h:67
Size PageGetFreeSpace(Page page)
Definition: bufpage.c:582
signed int int32
Definition: c.h:253
Datum Float8GetDatum(float8 X)
Definition: fmgr.c:2126
HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
Definition: execTuples.c:1115
int32 space_per_page
Definition: pgstatindex.c:117
uint16 OffsetNumber
Definition: off.h:24
Datum pg_relpagesbyid(PG_FUNCTION_ARGS)
Definition: pgstatindex.c:423
Datum pgstatindexbyid(PG_FUNCTION_ARGS)
Definition: pgstatindex.c:187
#define HASH_READ
Definition: hash.h:254
int64 nPendingHeapTuples
Definition: ginblock.h:73
struct GinIndexStat GinIndexStat
#define IS_BTREE(r)
Definition: pgstatindex.c:70
static Datum pgstatindex_impl(Relation rel, FunctionCallInfo fcinfo)
Definition: pgstatindex.c:215
int64 dead_items
Definition: pgstatindex.c:125
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3315
#define ERROR
Definition: elog.h:43
double float8
Definition: c.h:377
uint64 internal_pages
Definition: pgstatindex.c:85
struct HashIndexStat HashIndexStat
Datum pgstatindexbyid_v1_5(PG_FUNCTION_ARGS)
Definition: pgstatindex.c:204
static void GetHashPageStats(Page page, HashIndexStat *stats)
Definition: pgstatindex.c:709
uint32 hashm_version
Definition: hash.h:177
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:1031
#define BTPageGetMeta(p)
Definition: nbtree.h:106
static char * buf
Definition: pg_test_fsync.c:65
#define PG_GETARG_OID(n)
Definition: fmgr.h:231
#define FirstOffsetNumber
Definition: off.h:27
#define RelationGetRelationName(relation)
Definition: rel.h:433
unsigned int uint32
Definition: c.h:265
#define UInt32GetDatum(X)
Definition: postgres.h:501
#define IS_HASH(r)
Definition: pgstatindex.c:72
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:2102
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define ereport(elevel, rest)
Definition: elog.h:122
#define P_ISDELETED(opaque)
Definition: nbtree.h:179
List * textToQualifiedNameList(text *textval)
Definition: varlena.c:3071
#define GIN_SHARE
Definition: gin_private.h:44
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:232
BlockNumber pending_pages
Definition: pgstatindex.c:105
Datum pgstatginindex(PG_FUNCTION_ARGS)
Definition: pgstatindex.c:473
uint16 hashm_bsize
Definition: hash.h:180
Datum pgstatindex(PG_FUNCTION_ARGS)
Definition: pgstatindex.c:144
#define IS_GIN(r)
Definition: pgstatindex.c:71
#define HASH_METAPAGE
Definition: hash.h:146
uintptr_t Datum
Definition: postgres.h:374
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:297
#define LH_OVERFLOW_PAGE
Definition: hash.h:53
AttInMetadata * TupleDescGetAttInMetadata(TupleDesc tupdesc)
Definition: execTuples.c:1068
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3529
uint64 free_space
Definition: pgstatindex.c:91
BlockNumber btm_root
Definition: nbtree.h:100
#define RelationGetNumberOfBlocks(reln)
Definition: bufmgr.h:199
PG_FUNCTION_INFO_V1(pgstatindex)
void _hash_relbuf(Relation rel, Buffer buf)
Definition: hashpage.c:245
#define LH_BUCKET_PAGE
Definition: hash.h:54
PageHeaderData * PageHeader
Definition: bufpage.h:162
#define NULL
Definition: c.h:226
#define RELATION_IS_OTHER_TEMP(relation)
Definition: rel.h:530
uint64 leaf_pages
Definition: pgstatindex.c:86
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition: bufmgr.c:594
#define PageGetSpecialPointer(page)
Definition: bufpage.h:323
HashPageOpaqueData * HashPageOpaque
Definition: hash.h:84
Datum pg_relpages_v1_5(PG_FUNCTION_ARGS)
Definition: pgstatindex.c:402
#define MAXALIGN(LEN)
Definition: c.h:583
uint32 level
Definition: pgstatindex.c:82
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:222
#define PageGetSpecialSize(page)
Definition: bufpage.h:297
int32 ginVersion
Definition: ginblock.h:98
#define INT64_FORMAT
Definition: c.h:312
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:176
Size PageGetExactFreeSpace(Page page)
Definition: bufpage.c:606
uint16 hasho_flag
Definition: hash.h:80
static Datum values[MAXATTR]
Definition: bootstrap.c:162
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition: bufmgr.c:2588
#define Int32GetDatum(X)
Definition: postgres.h:487
#define PageIsNew(page)
Definition: bufpage.h:226
#define HashPageGetMeta(page)
Definition: hash.h:238
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define PG_GETARG_TEXT_P(n)
Definition: fmgr.h:269
uint32 btm_level
Definition: nbtree.h:101
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:88
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1117
Definition: c.h:434
#define PG_FUNCTION_ARGS
Definition: fmgr.h:150
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:97
uint64 deleted_pages
Definition: pgstatindex.c:88
#define GinPageGetMeta(p)
Definition: ginblock.h:103
#define elog
Definition: elog.h:219
Datum pg_relpages(PG_FUNCTION_ARGS)
Definition: pgstatindex.c:376
int Buffer
Definition: buf.h:23
BlockNumber bucket_pages
Definition: pgstatindex.c:119
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:151
Pointer Page
Definition: bufpage.h:74
uint64 max_avail
Definition: pgstatindex.c:90
int64 live_items
Definition: pgstatindex.c:124
BlockNumber nPendingPages
Definition: ginblock.h:72
#define P_ISLEAF(opaque)
Definition: nbtree.h:177