|
27 | 27 |
|
28 | 28 | #include"postgres.h"
|
29 | 29 |
|
| 30 | +#include"access/gin_private.h" |
30 | 31 | #include"access/heapam.h"
|
| 32 | +#include"access/htup_details.h" |
31 | 33 | #include"access/nbtree.h"
|
32 | 34 | #include"catalog/namespace.h"
|
33 | 35 | #include"funcapi.h"
|
|
39 | 41 |
|
40 | 42 | externDatumpgstatindex(PG_FUNCTION_ARGS);
|
41 | 43 | externDatumpg_relpages(PG_FUNCTION_ARGS);
|
| 44 | +externDatumpgstatginindex(PG_FUNCTION_ARGS); |
42 | 45 |
|
43 | 46 | PG_FUNCTION_INFO_V1(pgstatindex);
|
44 | 47 | PG_FUNCTION_INFO_V1(pg_relpages);
|
| 48 | +PG_FUNCTION_INFO_V1(pgstatginindex); |
45 | 49 |
|
46 | 50 | #defineIS_INDEX(r) ((r)->rd_rel->relkind == RELKIND_INDEX)
|
47 | 51 | #defineIS_BTREE(r) ((r)->rd_rel->relam == BTREE_AM_OID)
|
| 52 | +#defineIS_GIN(r) ((r)->rd_rel->relam == GIN_AM_OID) |
48 | 53 |
|
49 | 54 | #defineCHECK_PAGE_OFFSET_RANGE(pg,offnum) { \
|
50 | 55 | if ( !(FirstOffsetNumber <= (offnum) && \
|
@@ -79,6 +84,19 @@ typedef struct BTIndexStat
|
79 | 84 | uint64fragments;
|
80 | 85 | }BTIndexStat;
|
81 | 86 |
|
| 87 | +/* ------------------------------------------------ |
| 88 | + * A structure for a whole GIN index statistics |
| 89 | + * used by pgstatginindex(). |
| 90 | + * ------------------------------------------------ |
| 91 | + */ |
| 92 | +typedefstructGinIndexStat |
| 93 | +{ |
| 94 | +int32version; |
| 95 | + |
| 96 | +BlockNumberpending_pages; |
| 97 | +int64pending_tuples; |
| 98 | +}GinIndexStat; |
| 99 | + |
82 | 100 | /* ------------------------------------------------------
|
83 | 101 | * pgstatindex()
|
84 | 102 | *
|
@@ -292,3 +310,79 @@ pg_relpages(PG_FUNCTION_ARGS)
|
292 | 310 |
|
293 | 311 | PG_RETURN_INT64(relpages);
|
294 | 312 | }
|
| 313 | + |
| 314 | +/* ------------------------------------------------------ |
| 315 | + * pgstatginindex() |
| 316 | + * |
| 317 | + * Usage: SELECT * FROM pgstatginindex('ginindex'); |
| 318 | + * ------------------------------------------------------ |
| 319 | + */ |
| 320 | +Datum |
| 321 | +pgstatginindex(PG_FUNCTION_ARGS) |
| 322 | +{ |
| 323 | +Oidrelid=PG_GETARG_OID(0); |
| 324 | +Relationrel; |
| 325 | +Bufferbuffer; |
| 326 | +Pagepage; |
| 327 | +GinMetaPageData*metadata; |
| 328 | +GinIndexStatstats; |
| 329 | +HeapTupletuple; |
| 330 | +TupleDesctupleDesc; |
| 331 | +Datumvalues[3]; |
| 332 | +boolnulls[3]= {false, false, false}; |
| 333 | +Datumresult; |
| 334 | + |
| 335 | +if (!superuser()) |
| 336 | +ereport(ERROR, |
| 337 | +(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), |
| 338 | + (errmsg("must be superuser to use pgstattuple functions")))); |
| 339 | + |
| 340 | +rel=relation_open(relid,AccessShareLock); |
| 341 | + |
| 342 | +if (!IS_INDEX(rel)|| !IS_GIN(rel)) |
| 343 | +elog(ERROR,"relation \"%s\" is not a GIN index", |
| 344 | +RelationGetRelationName(rel)); |
| 345 | + |
| 346 | +/* |
| 347 | + * Reject attempts to read non-local temporary relations; we would be |
| 348 | + * likely to get wrong data since we have no visibility into the owning |
| 349 | + * session's local buffers. |
| 350 | + */ |
| 351 | +if (RELATION_IS_OTHER_TEMP(rel)) |
| 352 | +ereport(ERROR, |
| 353 | +(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 354 | +errmsg("cannot access temporary indexes of other sessions"))); |
| 355 | + |
| 356 | +/* |
| 357 | + * Read metapage |
| 358 | + */ |
| 359 | +buffer=ReadBuffer(rel,GIN_METAPAGE_BLKNO); |
| 360 | +LockBuffer(buffer,GIN_SHARE); |
| 361 | +page=BufferGetPage(buffer); |
| 362 | +metadata=GinPageGetMeta(page); |
| 363 | + |
| 364 | +stats.version=metadata->ginVersion; |
| 365 | +stats.pending_pages=metadata->nPendingPages; |
| 366 | +stats.pending_tuples=metadata->nPendingHeapTuples; |
| 367 | + |
| 368 | +UnlockReleaseBuffer(buffer); |
| 369 | +relation_close(rel,AccessShareLock); |
| 370 | + |
| 371 | +/* |
| 372 | + * Build a tuple descriptor for our result type |
| 373 | + */ |
| 374 | +if (get_call_result_type(fcinfo,NULL,&tupleDesc)!=TYPEFUNC_COMPOSITE) |
| 375 | +elog(ERROR,"return type must be a row type"); |
| 376 | + |
| 377 | +values[0]=Int32GetDatum(stats.version); |
| 378 | +values[1]=UInt32GetDatum(stats.pending_pages); |
| 379 | +values[2]=Int64GetDatum(stats.pending_tuples); |
| 380 | + |
| 381 | +/* |
| 382 | + * Build and return the tuple |
| 383 | + */ |
| 384 | +tuple=heap_form_tuple(tupleDesc,values,nulls); |
| 385 | +result=HeapTupleGetDatum(tuple); |
| 386 | + |
| 387 | +PG_RETURN_DATUM(result); |
| 388 | +} |