PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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/hash.h"
32#include "access/htup_details.h"
33#include "access/nbtree.h"
34#include "access/relation.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/read_stream.h"
41#include "utils/rel.h"
42#include "utils/varlena.h"
43
44
45/*
46 * Because of backward-compatibility issue, we have decided to have
47 * two types of interfaces, with regclass-type input arg and text-type
48 * input arg, for each function.
49 *
50 * Those functions which have text-type input arg will be deprecated
51 * in the future release.
52 */
59
65
67
68#define IS_INDEX(r) ((r)->rd_rel->relkind == RELKIND_INDEX)
69#define IS_BTREE(r) ((r)->rd_rel->relam == BTREE_AM_OID)
70#define IS_GIN(r) ((r)->rd_rel->relam == GIN_AM_OID)
71#define IS_HASH(r) ((r)->rd_rel->relam == HASH_AM_OID)
72
73/* ------------------------------------------------
74 * A structure for a whole btree index statistics
75 * used by pgstatindex().
76 * ------------------------------------------------
77 */
94
95/* ------------------------------------------------
96 * A structure for a whole GIN index statistics
97 * used by pgstatginindex().
98 * ------------------------------------------------
99 */
107
108/* ------------------------------------------------
109 * A structure for a whole HASH index statistics
110 * used by pgstathashindex().
111 * ------------------------------------------------
112 */
127
130static void GetHashPageStats(Page page, HashIndexStat *stats);
131
132/* ------------------------------------------------------
133 * pgstatindex()
134 *
135 * Usage: SELECT * FROM pgstatindex('t1_pkey');
136 *
137 * The superuser() check here must be kept as the library might be upgraded
138 * without the extension being upgraded, meaning that in pre-1.5 installations
139 * these functions could be called by any user.
140 * ------------------------------------------------------
141 */
142Datum
144{
146 Relation rel;
148
149 if (!superuser())
152 errmsg("must be superuser to use pgstattuple functions")));
153
156
157 PG_RETURN_DATUM(pgstatindex_impl(rel, fcinfo));
158}
159
160/*
161 * As of pgstattuple version 1.5, we no longer need to check if the user
162 * is a superuser because we REVOKE EXECUTE on the function from PUBLIC.
163 * Users can then grant access to it based on their policies.
164 *
165 * Otherwise identical to pgstatindex (above).
166 */
167Datum
179
180/*
181 * The superuser() check here must be kept as the library might be upgraded
182 * without the extension being upgraded, meaning that in pre-1.5 installations
183 * these functions could be called by any user.
184 */
185Datum
187{
188 Oid relid = PG_GETARG_OID(0);
189 Relation rel;
190
191 if (!superuser())
194 errmsg("must be superuser to use pgstattuple functions")));
195
196 rel = relation_open(relid, AccessShareLock);
197
198 PG_RETURN_DATUM(pgstatindex_impl(rel, fcinfo));
199}
200
201/* No need for superuser checks in v1.5, see above */
202Datum
204{
205 Oid relid = PG_GETARG_OID(0);
206 Relation rel;
207
208 rel = relation_open(relid, AccessShareLock);
209
210 PG_RETURN_DATUM(pgstatindex_impl(rel, fcinfo));
211}
212
213static Datum
215{
216 Datum result;
217 BlockNumber nblocks;
218 BlockNumber blkno;
222 ReadStream *stream;
224
225 if (!IS_INDEX(rel) || !IS_BTREE(rel))
228 errmsg("relation \"%s\" is not a btree index",
230
231 /*
232 * Reject attempts to read non-local temporary relations; we would be
233 * likely to get wrong data since we have no visibility into the owning
234 * session's local buffers.
235 */
236 if (RELATION_IS_OTHER_TEMP(rel))
239 errmsg("cannot access temporary tables of other sessions")));
240
241 /*
242 * A !indisready index could lead to ERRCODE_DATA_CORRUPTED later, so exit
243 * early. We're capable of assessing an indisready&&!indisvalid index,
244 * but the results could be confusing. For example, the index's size
245 * could be too low for a valid index of the table.
246 */
247 if (!rel->rd_index->indisvalid)
250 errmsg("index \"%s\" is not valid",
252
253 /*
254 * Read metapage
255 */
256 {
257 Buffer buffer = ReadBufferExtended(rel, MAIN_FORKNUM, 0, RBM_NORMAL, bstrategy);
258 Page page = BufferGetPage(buffer);
260
261 indexStat.version = metad->btm_version;
262 indexStat.level = metad->btm_level;
263 indexStat.root_blkno = metad->btm_root;
264
265 ReleaseBuffer(buffer);
266 }
267
268 /* -- init counters -- */
269 indexStat.internal_pages = 0;
270 indexStat.leaf_pages = 0;
271 indexStat.empty_pages = 0;
272 indexStat.deleted_pages = 0;
273
274 indexStat.max_avail = 0;
275 indexStat.free_space = 0;
276
277 indexStat.fragments = 0;
278
279 /*
280 * Scan all blocks except the metapage (0th page) using streaming reads
281 */
282 nblocks = RelationGetNumberOfBlocks(rel);
284
286 p.last_exclusive = nblocks;
287
288 /*
289 * It is safe to use batchmode as block_range_read_stream_cb takes no
290 * locks.
291 */
294 bstrategy,
295 rel,
298 &p,
299 0);
300
301 for (blkno = startblk; blkno < nblocks; blkno++)
302 {
303 Buffer buffer;
304 Page page;
305 BTPageOpaque opaque;
306
308
309 buffer = read_stream_next_buffer(stream, NULL);
311
312 page = BufferGetPage(buffer);
313 opaque = BTPageGetOpaque(page);
314
315 /*
316 * Determine page type, and update totals.
317 *
318 * Note that we arbitrarily bucket deleted pages together without
319 * considering if they're leaf pages or internal pages.
320 */
321 if (P_ISDELETED(opaque))
322 indexStat.deleted_pages++;
323 else if (P_IGNORE(opaque))
324 indexStat.empty_pages++; /* this is the "half dead" state */
325 else if (P_ISLEAF(opaque))
326 {
327 int max_avail;
328
329 max_avail = BLCKSZ - (BLCKSZ - ((PageHeader) page)->pd_special + SizeOfPageHeaderData);
330 indexStat.max_avail += max_avail;
331 indexStat.free_space += PageGetExactFreeSpace(page);
332
333 indexStat.leaf_pages++;
334
335 /*
336 * If the next leaf is on an earlier block, it means a
337 * fragmentation.
338 */
339 if (opaque->btpo_next != P_NONE && opaque->btpo_next < blkno)
340 indexStat.fragments++;
341 }
342 else
343 indexStat.internal_pages++;
344
345 UnlockReleaseBuffer(buffer);
346 }
347
349 read_stream_end(stream);
350
352
353 /*----------------------------
354 * Build a result tuple
355 *----------------------------
356 */
357 {
359 int j;
360 char *values[10];
361 HeapTuple tuple;
362
363 /* Build a tuple descriptor for our result type */
365 elog(ERROR, "return type must be a row type");
366
367 j = 0;
368 values[j++] = psprintf("%d", indexStat.version);
369 values[j++] = psprintf("%d", indexStat.level);
371 (1 + /* include the metapage in index_size */
372 indexStat.leaf_pages +
373 indexStat.internal_pages +
374 indexStat.deleted_pages +
375 indexStat.empty_pages) * BLCKSZ);
376 values[j++] = psprintf("%u", indexStat.root_blkno);
377 values[j++] = psprintf(INT64_FORMAT, indexStat.internal_pages);
378 values[j++] = psprintf(INT64_FORMAT, indexStat.leaf_pages);
379 values[j++] = psprintf(INT64_FORMAT, indexStat.empty_pages);
380 values[j++] = psprintf(INT64_FORMAT, indexStat.deleted_pages);
381 if (indexStat.max_avail > 0)
382 values[j++] = psprintf("%.2f",
383 100.0 - (double) indexStat.free_space / (double) indexStat.max_avail * 100.0);
384 else
385 values[j++] = pstrdup("NaN");
386 if (indexStat.leaf_pages > 0)
387 values[j++] = psprintf("%.2f",
388 (double) indexStat.fragments / (double) indexStat.leaf_pages * 100.0);
389 else
390 values[j++] = pstrdup("NaN");
391
393 values);
394
395 result = HeapTupleGetDatum(tuple);
396 }
397
398 return result;
399}
400
401/* --------------------------------------------------------
402 * pg_relpages()
403 *
404 * Get the number of pages of the table/index.
405 *
406 * Usage: SELECT pg_relpages('t1');
407 * SELECT pg_relpages('t1_pkey');
408 *
409 * Must keep superuser() check, see above.
410 * --------------------------------------------------------
411 */
412Datum
414{
416 Relation rel;
418
419 if (!superuser())
422 errmsg("must be superuser to use pgstattuple functions")));
423
426
428}
429
430/* No need for superuser checks in v1.5, see above */
431Datum
443
444/* Must keep superuser() check, see above. */
445Datum
447{
448 Oid relid = PG_GETARG_OID(0);
449 Relation rel;
450
451 if (!superuser())
454 errmsg("must be superuser to use pgstattuple functions")));
455
456 rel = relation_open(relid, AccessShareLock);
457
459}
460
461/* No need for superuser checks in v1.5, see above */
462Datum
464{
465 Oid relid = PG_GETARG_OID(0);
466 Relation rel;
467
468 rel = relation_open(relid, AccessShareLock);
469
471}
472
473static int64
475{
476 int64 relpages;
477
478 if (!RELKIND_HAS_STORAGE(rel->rd_rel->relkind))
481 errmsg("cannot get page count of relation \"%s\"",
484
485 /* note: this will work OK on non-local temp tables */
486
487 relpages = RelationGetNumberOfBlocks(rel);
488
490
491 return relpages;
492}
493
494/* ------------------------------------------------------
495 * pgstatginindex()
496 *
497 * Usage: SELECT * FROM pgstatginindex('ginindex');
498 *
499 * Must keep superuser() check, see above.
500 * ------------------------------------------------------
501 */
502Datum
504{
505 Oid relid = PG_GETARG_OID(0);
506
507 if (!superuser())
510 errmsg("must be superuser to use pgstattuple functions")));
511
513}
514
515/* No need for superuser checks in v1.5, see above */
516Datum
523
524Datum
526{
527 Relation rel;
528 Buffer buffer;
529 Page page;
530 GinMetaPageData *metadata;
531 GinIndexStat stats;
532 HeapTuple tuple;
534 Datum values[3];
535 bool nulls[3] = {false, false, false};
536 Datum result;
537
538 /*
539 * This uses relation_open() and not index_open(). The latter allows
540 * partitioned indexes, and these are forbidden here.
541 */
542 rel = relation_open(relid, AccessShareLock);
543
544 if (!IS_INDEX(rel) || !IS_GIN(rel))
547 errmsg("relation \"%s\" is not a GIN index",
549
550 /*
551 * Reject attempts to read non-local temporary relations; we would be
552 * likely to get wrong data since we have no visibility into the owning
553 * session's local buffers.
554 */
555 if (RELATION_IS_OTHER_TEMP(rel))
558 errmsg("cannot access temporary indexes of other sessions")));
559
560 /* see pgstatindex_impl */
561 if (!rel->rd_index->indisvalid)
564 errmsg("index \"%s\" is not valid",
566
567 /*
568 * Read metapage
569 */
570 buffer = ReadBuffer(rel, GIN_METAPAGE_BLKNO);
571 LockBuffer(buffer, GIN_SHARE);
572 page = BufferGetPage(buffer);
573 metadata = GinPageGetMeta(page);
574
575 stats.version = metadata->ginVersion;
576 stats.pending_pages = metadata->nPendingPages;
577 stats.pending_tuples = metadata->nPendingHeapTuples;
578
579 UnlockReleaseBuffer(buffer);
581
582 /*
583 * Build a tuple descriptor for our result type
584 */
586 elog(ERROR, "return type must be a row type");
587
588 values[0] = Int32GetDatum(stats.version);
591
592 /*
593 * Build and return the tuple
594 */
595 tuple = heap_form_tuple(tupleDesc, values, nulls);
596 result = HeapTupleGetDatum(tuple);
597
598 return result;
599}
600
601/* ------------------------------------------------------
602 * pgstathashindex()
603 *
604 * Usage: SELECT * FROM pgstathashindex('hashindex');
605 * ------------------------------------------------------
606 */
607Datum
609{
610 Oid relid = PG_GETARG_OID(0);
611 BlockNumber nblocks;
612 BlockNumber blkno;
613 Relation rel;
614 HashIndexStat stats;
615 BufferAccessStrategy bstrategy;
616 HeapTuple tuple;
618 Datum values[8];
619 bool nulls[8] = {0};
621 HashMetaPage metap;
622 float8 free_percent;
625 ReadStream *stream;
627
628 /*
629 * This uses relation_open() and not index_open(). The latter allows
630 * partitioned indexes, and these are forbidden here.
631 */
632 rel = relation_open(relid, AccessShareLock);
633
634 if (!IS_INDEX(rel) || !IS_HASH(rel))
637 errmsg("relation \"%s\" is not a hash index",
639
640 /*
641 * Reject attempts to read non-local temporary relations; we would be
642 * likely to get wrong data since we have no visibility into the owning
643 * session's local buffers.
644 */
645 if (RELATION_IS_OTHER_TEMP(rel))
648 errmsg("cannot access temporary indexes of other sessions")));
649
650 /* see pgstatindex_impl */
651 if (!rel->rd_index->indisvalid)
654 errmsg("index \"%s\" is not valid",
656
657 /* Get the information we need from the metapage. */
658 memset(&stats, 0, sizeof(stats));
661 stats.version = metap->hashm_version;
662 stats.space_per_page = metap->hashm_bsize;
663 _hash_relbuf(rel, metabuf);
664
665 /* Get the current relation length */
666 nblocks = RelationGetNumberOfBlocks(rel);
667
668 /* prepare access strategy for this index */
669 bstrategy = GetAccessStrategy(BAS_BULKREAD);
670
671 /* Scan all blocks except the metapage (0th page) using streaming reads */
673
675 p.last_exclusive = nblocks;
676
677 /*
678 * It is safe to use batchmode as block_range_read_stream_cb takes no
679 * locks.
680 */
683 bstrategy,
684 rel,
687 &p,
688 0);
689
690 for (blkno = startblk; blkno < nblocks; blkno++)
691 {
692 Buffer buf;
693 Page page;
694
696
699 page = BufferGetPage(buf);
700
701 if (PageIsNew(page))
702 stats.unused_pages++;
703 else if (PageGetSpecialSize(page) !=
707 errmsg("index \"%s\" contains corrupted page at block %u",
710 else
711 {
712 HashPageOpaque opaque;
713 int pagetype;
714
715 opaque = HashPageGetOpaque(page);
716 pagetype = opaque->hasho_flag & LH_PAGE_TYPE;
717
719 {
720 stats.bucket_pages++;
721 GetHashPageStats(page, &stats);
722 }
723 else if (pagetype == LH_OVERFLOW_PAGE)
724 {
725 stats.overflow_pages++;
726 GetHashPageStats(page, &stats);
727 }
728 else if (pagetype == LH_BITMAP_PAGE)
729 stats.bitmap_pages++;
730 else if (pagetype == LH_UNUSED_PAGE)
731 stats.unused_pages++;
732 else
735 errmsg("unexpected page type 0x%04X in HASH index \"%s\" block %u",
738 }
740 }
741
743 read_stream_end(stream);
744
745 /* Done accessing the index */
747
748 /* Count unused pages as free space. */
749 stats.free_space += (uint64) stats.unused_pages * stats.space_per_page;
750
751 /*
752 * Total space available for tuples excludes the metapage and the bitmap
753 * pages.
754 */
755 total_space = (uint64) (nblocks - (stats.bitmap_pages + 1)) *
756 stats.space_per_page;
757
758 if (total_space == 0)
759 free_percent = 0.0;
760 else
761 free_percent = 100.0 * stats.free_space / total_space;
762
763 /*
764 * Build a tuple descriptor for our result type
765 */
767 elog(ERROR, "return type must be a row type");
768
770
771 /*
772 * Build and return the tuple
773 */
774 values[0] = Int32GetDatum(stats.version);
779 values[5] = Int64GetDatum(stats.live_items);
780 values[6] = Int64GetDatum(stats.dead_items);
781 values[7] = Float8GetDatum(free_percent);
782 tuple = heap_form_tuple(tupleDesc, values, nulls);
783
785}
786
787/* -------------------------------------------------
788 * GetHashPageStats()
789 *
790 * Collect statistics of single hash page
791 * -------------------------------------------------
792 */
793static void
795{
797 int off;
798
799 /* count live and dead tuples, and free space */
800 for (off = FirstOffsetNumber; off <= maxoff; off++)
801 {
802 ItemId id = PageGetItemId(page, off);
803
804 if (!ItemIdIsDead(id))
805 stats->live_items++;
806 else
807 stats->dead_items++;
808 }
809 stats->free_space += PageGetExactFreeSpace(page);
810}
uint32 BlockNumber
Definition block.h:31
static Datum values[MAXATTR]
Definition bootstrap.c:188
int Buffer
Definition buf.h:23
#define InvalidBuffer
Definition buf.h:25
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition bufmgr.c:4357
void ReleaseBuffer(Buffer buffer)
Definition bufmgr.c:5505
void UnlockReleaseBuffer(Buffer buffer)
Definition bufmgr.c:5522
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition bufmgr.c:921
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition bufmgr.c:874
@ BAS_BULKREAD
Definition bufmgr.h:37
#define RelationGetNumberOfBlocks(reln)
Definition bufmgr.h:307
static Page BufferGetPage(Buffer buffer)
Definition bufmgr.h:470
@ BUFFER_LOCK_SHARE
Definition bufmgr.h:210
static void LockBuffer(Buffer buffer, BufferLockMode mode)
Definition bufmgr.h:332
@ RBM_NORMAL
Definition bufmgr.h:46
Size PageGetExactFreeSpace(const PageData *page)
Definition bufpage.c:957
PageHeaderData * PageHeader
Definition bufpage.h:199
static uint16 PageGetSpecialSize(const PageData *page)
Definition bufpage.h:342
static bool PageIsNew(const PageData *page)
Definition bufpage.h:259
#define SizeOfPageHeaderData
Definition bufpage.h:242
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
Definition bufpage.h:269
PageData * Page
Definition bufpage.h:81
static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)
Definition bufpage.h:397
#define MAXALIGN(LEN)
Definition c.h:898
#define INT64_FORMAT
Definition c.h:636
#define Assert(condition)
Definition c.h:945
int64_t int64
Definition c.h:615
double float8
Definition c.h:716
int32_t int32
Definition c.h:614
uint64_t uint64
Definition c.h:619
uint32_t uint32
Definition c.h:618
int errcode(int sqlerrcode)
Definition elog.c:874
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
AttInMetadata * TupleDescGetAttInMetadata(TupleDesc tupdesc)
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define PG_GETARG_TEXT_PP(n)
Definition fmgr.h:310
#define PG_RETURN_INT64(x)
Definition fmgr.h:370
#define PG_FUNCTION_INFO_V1(funcname)
Definition fmgr.h:417
#define PG_RETURN_DATUM(x)
Definition fmgr.h:354
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype)
Definition freelist.c:461
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition funcapi.c:276
@ TYPEFUNC_COMPOSITE
Definition funcapi.h:149
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
Definition funcapi.h:230
#define GIN_SHARE
Definition gin_private.h:52
#define GIN_METAPAGE_BLKNO
Definition ginblock.h:51
#define GinPageGetMeta(p)
Definition ginblock.h:104
#define HashPageGetOpaque(page)
Definition hash.h:88
#define LH_BUCKET_PAGE
Definition hash.h:55
#define LH_UNUSED_PAGE
Definition hash.h:53
#define LH_META_PAGE
Definition hash.h:57
#define HashPageGetMeta(page)
Definition hash.h:323
#define HASH_READ
Definition hash.h:339
#define HASH_METAPAGE
Definition hash.h:198
#define LH_PAGE_TYPE
Definition hash.h:63
#define LH_BITMAP_PAGE
Definition hash.h:56
#define LH_OVERFLOW_PAGE
Definition hash.h:54
void _hash_relbuf(Relation rel, Buffer buf)
Definition hashpage.c:266
Buffer _hash_getbuf(Relation rel, BlockNumber blkno, int access, int flags)
Definition hashpage.c:70
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1037
int j
Definition isn.c:78
#define ItemIdIsDead(itemId)
Definition itemid.h:113
#define AccessShareLock
Definition lockdefs.h:36
char * pstrdup(const char *in)
Definition mcxt.c:1781
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:123
RangeVar * makeRangeVarFromNameList(const List *names)
Definition namespace.c:3626
#define BTPageGetMeta(p)
Definition nbtree.h:122
#define P_ISLEAF(opaque)
Definition nbtree.h:221
#define BTPageGetOpaque(page)
Definition nbtree.h:74
#define P_ISDELETED(opaque)
Definition nbtree.h:223
#define P_NONE
Definition nbtree.h:213
#define BTREE_METAPAGE
Definition nbtree.h:149
#define P_IGNORE(opaque)
Definition nbtree.h:226
static char * errmsg
uint16 OffsetNumber
Definition off.h:24
#define FirstOffsetNumber
Definition off.h:27
int errdetail_relkind_not_supported(char relkind)
Definition pg_class.c:24
NameData relname
Definition pg_class.h:40
static char buf[DEFAULT_XLOG_SEG_SIZE]
Datum pgstatindexbyid(PG_FUNCTION_ARGS)
Datum pgstatindexbyid_v1_5(PG_FUNCTION_ARGS)
Datum pgstatindex_v1_5(PG_FUNCTION_ARGS)
#define IS_BTREE(r)
Definition pgstatindex.c:69
#define IS_HASH(r)
Definition pgstatindex.c:71
static void GetHashPageStats(Page page, HashIndexStat *stats)
static int64 pg_relpages_impl(Relation rel)
Datum pgstatginindex_v1_5(PG_FUNCTION_ARGS)
Datum pg_relpagesbyid(PG_FUNCTION_ARGS)
Datum pg_relpages(PG_FUNCTION_ARGS)
Datum pgstatginindex_internal(Oid relid, FunctionCallInfo fcinfo)
Datum pg_relpages_v1_5(PG_FUNCTION_ARGS)
#define IS_INDEX(r)
Definition pgstatindex.c:68
static Datum pgstatindex_impl(Relation rel, FunctionCallInfo fcinfo)
Datum pg_relpagesbyid_v1_5(PG_FUNCTION_ARGS)
Datum pgstatginindex(PG_FUNCTION_ARGS)
#define IS_GIN(r)
Definition pgstatindex.c:70
Datum pgstathashindex(PG_FUNCTION_ARGS)
Datum pgstatindex(PG_FUNCTION_ARGS)
static Datum Int64GetDatum(int64 X)
Definition postgres.h:413
uint64_t Datum
Definition postgres.h:70
static Datum Float8GetDatum(float8 X)
Definition postgres.h:502
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212
static Datum UInt32GetDatum(uint32 X)
Definition postgres.h:232
unsigned int Oid
static int fb(int x)
char * psprintf(const char *fmt,...)
Definition psprintf.c:43
Buffer read_stream_next_buffer(ReadStream *stream, void **per_buffer_data)
ReadStream * read_stream_begin_relation(int flags, BufferAccessStrategy strategy, Relation rel, ForkNumber forknum, ReadStreamBlockNumberCB callback, void *callback_private_data, size_t per_buffer_data_size)
void read_stream_end(ReadStream *stream)
BlockNumber block_range_read_stream_cb(ReadStream *stream, void *callback_private_data, void *per_buffer_data)
#define READ_STREAM_USE_BATCHING
Definition read_stream.h:64
#define READ_STREAM_FULL
Definition read_stream.h:43
#define RelationGetRelationName(relation)
Definition rel.h:548
#define RELATION_IS_OTHER_TEMP(relation)
Definition rel.h:667
@ MAIN_FORKNUM
Definition relpath.h:58
void relation_close(Relation relation, LOCKMODE lockmode)
Definition relation.c:205
Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
Definition relation.c:137
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition relation.c:47
uint64 max_avail
Definition pgstatindex.c:89
uint32 level
Definition pgstatindex.c:81
uint64 empty_pages
Definition pgstatindex.c:86
uint64 deleted_pages
Definition pgstatindex.c:87
uint64 internal_pages
Definition pgstatindex.c:84
uint64 leaf_pages
Definition pgstatindex.c:85
uint32 version
Definition pgstatindex.c:80
uint64 fragments
Definition pgstatindex.c:92
BlockNumber root_blkno
Definition pgstatindex.c:82
uint64 free_space
Definition pgstatindex.c:90
BlockNumber btpo_next
Definition nbtree.h:66
BlockNumber pending_pages
int64 pending_tuples
int32 ginVersion
Definition ginblock.h:99
BlockNumber nPendingPages
Definition ginblock.h:73
int64 nPendingHeapTuples
Definition ginblock.h:74
BlockNumber bitmap_pages
BlockNumber overflow_pages
BlockNumber bucket_pages
BlockNumber unused_pages
uint64 free_space
int32 space_per_page
uint32 hashm_version
Definition hash.h:247
uint16 hashm_bsize
Definition hash.h:250
uint16 hasho_flag
Definition hash.h:82
Form_pg_index rd_index
Definition rel.h:192
Form_pg_class rd_rel
Definition rel.h:111
Definition c.h:778
bool superuser(void)
Definition superuser.c:47
List * textToQualifiedNameList(text *textval)
Definition varlena.c:2719