/* *Thesuperuser()checkheremustbekeptasthelibrarymightbeupgraded *withouttheextensionbeingupgraded,meaningthatinpre-1.5installations *thesefunctionscouldbecalledbyanyuser.
*/
Datum
pgstatindexbyid(PG_FUNCTION_ARGS)
{
Oid relid = PG_GETARG_OID(0);
Relation rel;
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to use pgstattuple functions")));
rel = relation_open(relid, AccessShareLock);
PG_RETURN_DATUM(pgstatindex_impl(rel, fcinfo));
}
/* No need for superuser checks in v1.5, see above */
Datum
pgstatindexbyid_v1_5(PG_FUNCTION_ARGS)
{
Oid relid = PG_GETARG_OID(0);
Relation rel;
rel = relation_open(relid, AccessShareLock);
PG_RETURN_DATUM(pgstatindex_impl(rel, fcinfo));
}
static Datum
pgstatindex_impl(Relation rel, FunctionCallInfo fcinfo)
{
Datum result;
BlockNumber nblocks;
BlockNumber blkno;
BTIndexStat indexStat;
BufferAccessStrategy bstrategy = GetAccessStrategy(BAS_BULKREAD);
if (!IS_INDEX(rel) || !IS_BTREE(rel))
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("relation \"%s\" is not a btree index",
RelationGetRelationName(rel))));
/* *Rejectattemptstoreadnon-localtemporaryrelations;wewouldbe *likelytogetwrongdatasincewehavenovisibilityintotheowning *session'slocalbuffers.
*/ if (RELATION_IS_OTHER_TEMP(rel))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot access temporary tables of other sessions")));
/* *A!indisreadyindexcouldleadtoERRCODE_DATA_CORRUPTEDlater,soexit *early.We'recapableofassessinganindisready&&!indisvalidindex, *buttheresultscouldbeconfusing.Forexample,theindex'ssize *couldbetoolowforavalidindexofthetable.
*/ if (!rel->rd_index->indisvalid)
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("index \"%s\" is not valid",
RelationGetRelationName(rel))));
/* *Determinepagetype,andupdatetotals. * *Notethatwearbitrarilybucketdeletedpagestogetherwithout *consideringifthey'releafpagesorinternalpages.
*/ if (P_ISDELETED(opaque))
indexStat.deleted_pages++; elseif (P_IGNORE(opaque))
indexStat.empty_pages++; /* this is the "half dead" state */ elseif (P_ISLEAF(opaque))
{ int max_avail;
/* Build a tuple descriptor for our result type */ if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
elog(ERROR, "return type must be a row type");
/* No need for superuser checks in v1.5, see above */
Datum
pg_relpages_v1_5(PG_FUNCTION_ARGS)
{
text *relname = PG_GETARG_TEXT_PP(0);
Relation rel;
RangeVar *relrv;
if (!RELKIND_HAS_STORAGE(rel->rd_rel->relkind))
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("cannot get page count of relation \"%s\"",
RelationGetRelationName(rel)),
errdetail_relkind_not_supported(rel->rd_rel->relkind)));
/* note: this will work OK on non-local temp tables */
relpages = RelationGetNumberOfBlocks(rel);
relation_close(rel, AccessShareLock);
return relpages;
}
/* ------------------------------------------------------ *pgstatginindex() * *Usage:SELECT*FROMpgstatginindex('ginindex'); * *Mustkeepsuperuser()check,seeabove. *------------------------------------------------------
*/
Datum
pgstatginindex(PG_FUNCTION_ARGS)
{
Oid relid = PG_GETARG_OID(0);
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to use pgstattuple functions")));
Datum
pgstatginindex_internal(Oid relid, FunctionCallInfo fcinfo)
{
Relation rel;
Buffer buffer;
Page page;
GinMetaPageData *metadata;
GinIndexStat stats;
HeapTuple tuple;
TupleDesc tupleDesc;
Datum values[3]; bool nulls[3] = {false, false, false};
Datum result;
rel = relation_open(relid, AccessShareLock);
if (!IS_INDEX(rel) || !IS_GIN(rel))
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("relation \"%s\" is not a GIN index",
RelationGetRelationName(rel))));
/* *Rejectattemptstoreadnon-localtemporaryrelations;wewouldbe *likelytogetwrongdatasincewehavenovisibilityintotheowning *session'slocalbuffers.
*/ if (RELATION_IS_OTHER_TEMP(rel))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot access temporary indexes of other sessions")));
/* see pgstatindex_impl */ if (!rel->rd_index->indisvalid)
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("index \"%s\" is not valid",
RelationGetRelationName(rel))));
/* *Buildatupledescriptorforourresulttype
*/ if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
elog(ERROR, "return type must be a row type");
if (!IS_INDEX(rel) || !IS_HASH(rel))
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("relation \"%s\" is not a hash index",
RelationGetRelationName(rel))));
/* *Rejectattemptstoreadnon-localtemporaryrelations;wewouldbe *likelytogetwrongdatasincewehavenovisibilityintotheowning *session'slocalbuffers.
*/ if (RELATION_IS_OTHER_TEMP(rel))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot access temporary indexes of other sessions")));
/* see pgstatindex_impl */ if (!rel->rd_index->indisvalid)
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("index \"%s\" is not valid",
RelationGetRelationName(rel))));
/* Get the information we need from the metapage. */
memset(&stats, 0, sizeof(stats));
metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_READ, LH_META_PAGE);
metap = HashPageGetMeta(BufferGetPage(metabuf));
stats.version = metap->hashm_version;
stats.space_per_page = metap->hashm_bsize;
_hash_relbuf(rel, metabuf);
/* Get the current relation length */
nblocks = RelationGetNumberOfBlocks(rel);
/* prepare access strategy for this index */
bstrategy = GetAccessStrategy(BAS_BULKREAD);
/* Start from blkno 1 as 0th block is metapage */ for (blkno = 1; blkno < nblocks; blkno++)
{
Buffer buf;
Page page;
/* *Buildatupledescriptorforourresulttype
*/ if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
elog(ERROR, "return type must be a row type");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.