LCOV - code coverage report
Current view: top level - src/backend/utils/adt - pgstatfuncs.c (source / functions) Hit Total Coverage
Test: PostgreSQL Lines: 56 762 7.3 %
Date: 2017-09-29 13:40:31 Functions: 12 90 13.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * pgstatfuncs.c
       4             :  *    Functions for accessing the statistics collector data
       5             :  *
       6             :  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  *
      10             :  * IDENTIFICATION
      11             :  *    src/backend/utils/adt/pgstatfuncs.c
      12             :  *
      13             :  *-------------------------------------------------------------------------
      14             :  */
      15             : #include "postgres.h"
      16             : 
      17             : #include "access/htup_details.h"
      18             : #include "catalog/pg_authid.h"
      19             : #include "catalog/pg_type.h"
      20             : #include "common/ip.h"
      21             : #include "funcapi.h"
      22             : #include "miscadmin.h"
      23             : #include "pgstat.h"
      24             : #include "postmaster/postmaster.h"
      25             : #include "storage/proc.h"
      26             : #include "storage/procarray.h"
      27             : #include "utils/acl.h"
      28             : #include "utils/builtins.h"
      29             : #include "utils/inet.h"
      30             : #include "utils/timestamp.h"
      31             : 
      32             : #define UINT32_ACCESS_ONCE(var)      ((uint32)(*((volatile uint32 *)&(var))))
      33             : 
      34             : /* Global bgwriter statistics, from bgwriter.c */
      35             : extern PgStat_MsgBgWriter bgwriterStats;
      36             : 
      37             : Datum
      38          20 : pg_stat_get_numscans(PG_FUNCTION_ARGS)
      39             : {
      40          20 :     Oid         relid = PG_GETARG_OID(0);
      41             :     int64       result;
      42             :     PgStat_StatTabEntry *tabentry;
      43             : 
      44          20 :     if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
      45           0 :         result = 0;
      46             :     else
      47          20 :         result = (int64) (tabentry->numscans);
      48             : 
      49          20 :     PG_RETURN_INT64(result);
      50             : }
      51             : 
      52             : 
      53             : Datum
      54           2 : pg_stat_get_tuples_returned(PG_FUNCTION_ARGS)
      55             : {
      56           2 :     Oid         relid = PG_GETARG_OID(0);
      57             :     int64       result;
      58             :     PgStat_StatTabEntry *tabentry;
      59             : 
      60           2 :     if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
      61           0 :         result = 0;
      62             :     else
      63           2 :         result = (int64) (tabentry->tuples_returned);
      64             : 
      65           2 :     PG_RETURN_INT64(result);
      66             : }
      67             : 
      68             : 
      69             : Datum
      70           8 : pg_stat_get_tuples_fetched(PG_FUNCTION_ARGS)
      71             : {
      72           8 :     Oid         relid = PG_GETARG_OID(0);
      73             :     int64       result;
      74             :     PgStat_StatTabEntry *tabentry;
      75             : 
      76           8 :     if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
      77           0 :         result = 0;
      78             :     else
      79           8 :         result = (int64) (tabentry->tuples_fetched);
      80             : 
      81           8 :     PG_RETURN_INT64(result);
      82             : }
      83             : 
      84             : 
      85             : Datum
      86           8 : pg_stat_get_tuples_inserted(PG_FUNCTION_ARGS)
      87             : {
      88           8 :     Oid         relid = PG_GETARG_OID(0);
      89             :     int64       result;
      90             :     PgStat_StatTabEntry *tabentry;
      91             : 
      92           8 :     if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
      93           2 :         result = 0;
      94             :     else
      95           6 :         result = (int64) (tabentry->tuples_inserted);
      96             : 
      97           8 :     PG_RETURN_INT64(result);
      98             : }
      99             : 
     100             : 
     101             : Datum
     102           5 : pg_stat_get_tuples_updated(PG_FUNCTION_ARGS)
     103             : {
     104           5 :     Oid         relid = PG_GETARG_OID(0);
     105             :     int64       result;
     106             :     PgStat_StatTabEntry *tabentry;
     107             : 
     108           5 :     if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
     109           0 :         result = 0;
     110             :     else
     111           5 :         result = (int64) (tabentry->tuples_updated);
     112             : 
     113           5 :     PG_RETURN_INT64(result);
     114             : }
     115             : 
     116             : 
     117             : Datum
     118           5 : pg_stat_get_tuples_deleted(PG_FUNCTION_ARGS)
     119             : {
     120           5 :     Oid         relid = PG_GETARG_OID(0);
     121             :     int64       result;
     122             :     PgStat_StatTabEntry *tabentry;
     123             : 
     124           5 :     if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
     125           0 :         result = 0;
     126             :     else
     127           5 :         result = (int64) (tabentry->tuples_deleted);
     128             : 
     129           5 :     PG_RETURN_INT64(result);
     130             : }
     131             : 
     132             : 
     133             : Datum
     134           0 : pg_stat_get_tuples_hot_updated(PG_FUNCTION_ARGS)
     135             : {
     136           0 :     Oid         relid = PG_GETARG_OID(0);
     137             :     int64       result;
     138             :     PgStat_StatTabEntry *tabentry;
     139             : 
     140           0 :     if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
     141           0 :         result = 0;
     142             :     else
     143           0 :         result = (int64) (tabentry->tuples_hot_updated);
     144             : 
     145           0 :     PG_RETURN_INT64(result);
     146             : }
     147             : 
     148             : 
     149             : Datum
     150           5 : pg_stat_get_live_tuples(PG_FUNCTION_ARGS)
     151             : {
     152           5 :     Oid         relid = PG_GETARG_OID(0);
     153             :     int64       result;
     154             :     PgStat_StatTabEntry *tabentry;
     155             : 
     156           5 :     if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
     157           0 :         result = 0;
     158             :     else
     159           5 :         result = (int64) (tabentry->n_live_tuples);
     160             : 
     161           5 :     PG_RETURN_INT64(result);
     162             : }
     163             : 
     164             : 
     165             : Datum
     166           5 : pg_stat_get_dead_tuples(PG_FUNCTION_ARGS)
     167             : {
     168           5 :     Oid         relid = PG_GETARG_OID(0);
     169             :     int64       result;
     170             :     PgStat_StatTabEntry *tabentry;
     171             : 
     172           5 :     if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
     173           0 :         result = 0;
     174             :     else
     175           5 :         result = (int64) (tabentry->n_dead_tuples);
     176             : 
     177           5 :     PG_RETURN_INT64(result);
     178             : }
     179             : 
     180             : 
     181             : Datum
     182           0 : pg_stat_get_mod_since_analyze(PG_FUNCTION_ARGS)
     183             : {
     184           0 :     Oid         relid = PG_GETARG_OID(0);
     185             :     int64       result;
     186             :     PgStat_StatTabEntry *tabentry;
     187             : 
     188           0 :     if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
     189           0 :         result = 0;
     190             :     else
     191           0 :         result = (int64) (tabentry->changes_since_analyze);
     192             : 
     193           0 :     PG_RETURN_INT64(result);
     194             : }
     195             : 
     196             : 
     197             : Datum
     198           8 : pg_stat_get_blocks_fetched(PG_FUNCTION_ARGS)
     199             : {
     200           8 :     Oid         relid = PG_GETARG_OID(0);
     201             :     int64       result;
     202             :     PgStat_StatTabEntry *tabentry;
     203             : 
     204           8 :     if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
     205           0 :         result = 0;
     206             :     else
     207           8 :         result = (int64) (tabentry->blocks_fetched);
     208             : 
     209           8 :     PG_RETURN_INT64(result);
     210             : }
     211             : 
     212             : 
     213             : Datum
     214          16 : pg_stat_get_blocks_hit(PG_FUNCTION_ARGS)
     215             : {
     216          16 :     Oid         relid = PG_GETARG_OID(0);
     217             :     int64       result;
     218             :     PgStat_StatTabEntry *tabentry;
     219             : 
     220          16 :     if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
     221           0 :         result = 0;
     222             :     else
     223          16 :         result = (int64) (tabentry->blocks_hit);
     224             : 
     225          16 :     PG_RETURN_INT64(result);
     226             : }
     227             : 
     228             : Datum
     229           0 : pg_stat_get_last_vacuum_time(PG_FUNCTION_ARGS)
     230             : {
     231           0 :     Oid         relid = PG_GETARG_OID(0);
     232             :     TimestampTz result;
     233             :     PgStat_StatTabEntry *tabentry;
     234             : 
     235           0 :     if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
     236           0 :         result = 0;
     237             :     else
     238           0 :         result = tabentry->vacuum_timestamp;
     239             : 
     240           0 :     if (result == 0)
     241           0 :         PG_RETURN_NULL();
     242             :     else
     243           0 :         PG_RETURN_TIMESTAMPTZ(result);
     244             : }
     245             : 
     246             : Datum
     247           0 : pg_stat_get_last_autovacuum_time(PG_FUNCTION_ARGS)
     248             : {
     249           0 :     Oid         relid = PG_GETARG_OID(0);
     250             :     TimestampTz result;
     251             :     PgStat_StatTabEntry *tabentry;
     252             : 
     253           0 :     if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
     254           0 :         result = 0;
     255             :     else
     256           0 :         result = tabentry->autovac_vacuum_timestamp;
     257             : 
     258           0 :     if (result == 0)
     259           0 :         PG_RETURN_NULL();
     260             :     else
     261           0 :         PG_RETURN_TIMESTAMPTZ(result);
     262             : }
     263             : 
     264             : Datum
     265           0 : pg_stat_get_last_analyze_time(PG_FUNCTION_ARGS)
     266             : {
     267           0 :     Oid         relid = PG_GETARG_OID(0);
     268             :     TimestampTz result;
     269             :     PgStat_StatTabEntry *tabentry;
     270             : 
     271           0 :     if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
     272           0 :         result = 0;
     273             :     else
     274           0 :         result = tabentry->analyze_timestamp;
     275             : 
     276           0 :     if (result == 0)
     277           0 :         PG_RETURN_NULL();
     278             :     else
     279           0 :         PG_RETURN_TIMESTAMPTZ(result);
     280             : }
     281             : 
     282             : Datum
     283           0 : pg_stat_get_last_autoanalyze_time(PG_FUNCTION_ARGS)
     284             : {
     285           0 :     Oid         relid = PG_GETARG_OID(0);
     286             :     TimestampTz result;
     287             :     PgStat_StatTabEntry *tabentry;
     288             : 
     289           0 :     if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
     290           0 :         result = 0;
     291             :     else
     292           0 :         result = tabentry->autovac_analyze_timestamp;
     293             : 
     294           0 :     if (result == 0)
     295           0 :         PG_RETURN_NULL();
     296             :     else
     297           0 :         PG_RETURN_TIMESTAMPTZ(result);
     298             : }
     299             : 
     300             : Datum
     301           0 : pg_stat_get_vacuum_count(PG_FUNCTION_ARGS)
     302             : {
     303           0 :     Oid         relid = PG_GETARG_OID(0);
     304             :     int64       result;
     305             :     PgStat_StatTabEntry *tabentry;
     306             : 
     307           0 :     if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
     308           0 :         result = 0;
     309             :     else
     310           0 :         result = (int64) (tabentry->vacuum_count);
     311             : 
     312           0 :     PG_RETURN_INT64(result);
     313             : }
     314             : 
     315             : Datum
     316           0 : pg_stat_get_autovacuum_count(PG_FUNCTION_ARGS)
     317             : {
     318           0 :     Oid         relid = PG_GETARG_OID(0);
     319             :     int64       result;
     320             :     PgStat_StatTabEntry *tabentry;
     321             : 
     322           0 :     if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
     323           0 :         result = 0;
     324             :     else
     325           0 :         result = (int64) (tabentry->autovac_vacuum_count);
     326             : 
     327           0 :     PG_RETURN_INT64(result);
     328             : }
     329             : 
     330             : Datum
     331           0 : pg_stat_get_analyze_count(PG_FUNCTION_ARGS)
     332             : {
     333           0 :     Oid         relid = PG_GETARG_OID(0);
     334             :     int64       result;
     335             :     PgStat_StatTabEntry *tabentry;
     336             : 
     337           0 :     if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
     338           0 :         result = 0;
     339             :     else
     340           0 :         result = (int64) (tabentry->analyze_count);
     341             : 
     342           0 :     PG_RETURN_INT64(result);
     343             : }
     344             : 
     345             : Datum
     346           0 : pg_stat_get_autoanalyze_count(PG_FUNCTION_ARGS)
     347             : {
     348           0 :     Oid         relid = PG_GETARG_OID(0);
     349             :     int64       result;
     350             :     PgStat_StatTabEntry *tabentry;
     351             : 
     352           0 :     if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
     353           0 :         result = 0;
     354             :     else
     355           0 :         result = (int64) (tabentry->autovac_analyze_count);
     356             : 
     357           0 :     PG_RETURN_INT64(result);
     358             : }
     359             : 
     360             : Datum
     361           0 : pg_stat_get_function_calls(PG_FUNCTION_ARGS)
     362             : {
     363           0 :     Oid         funcid = PG_GETARG_OID(0);
     364             :     PgStat_StatFuncEntry *funcentry;
     365             : 
     366           0 :     if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
     367           0 :         PG_RETURN_NULL();
     368           0 :     PG_RETURN_INT64(funcentry->f_numcalls);
     369             : }
     370             : 
     371             : Datum
     372           0 : pg_stat_get_function_total_time(PG_FUNCTION_ARGS)
     373             : {
     374           0 :     Oid         funcid = PG_GETARG_OID(0);
     375             :     PgStat_StatFuncEntry *funcentry;
     376             : 
     377           0 :     if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
     378           0 :         PG_RETURN_NULL();
     379             :     /* convert counter from microsec to millisec for display */
     380           0 :     PG_RETURN_FLOAT8(((double) funcentry->f_total_time) / 1000.0);
     381             : }
     382             : 
     383             : Datum
     384           0 : pg_stat_get_function_self_time(PG_FUNCTION_ARGS)
     385             : {
     386           0 :     Oid         funcid = PG_GETARG_OID(0);
     387             :     PgStat_StatFuncEntry *funcentry;
     388             : 
     389           0 :     if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
     390           0 :         PG_RETURN_NULL();
     391             :     /* convert counter from microsec to millisec for display */
     392           0 :     PG_RETURN_FLOAT8(((double) funcentry->f_self_time) / 1000.0);
     393             : }
     394             : 
     395             : Datum
     396           0 : pg_stat_get_backend_idset(PG_FUNCTION_ARGS)
     397             : {
     398             :     FuncCallContext *funcctx;
     399             :     int        *fctx;
     400             :     int32       result;
     401             : 
     402             :     /* stuff done only on the first call of the function */
     403           0 :     if (SRF_IS_FIRSTCALL())
     404             :     {
     405             :         /* create a function context for cross-call persistence */
     406           0 :         funcctx = SRF_FIRSTCALL_INIT();
     407             : 
     408           0 :         fctx = MemoryContextAlloc(funcctx->multi_call_memory_ctx,
     409             :                                   2 * sizeof(int));
     410           0 :         funcctx->user_fctx = fctx;
     411             : 
     412           0 :         fctx[0] = 0;
     413           0 :         fctx[1] = pgstat_fetch_stat_numbackends();
     414             :     }
     415             : 
     416             :     /* stuff done on every call of the function */
     417           0 :     funcctx = SRF_PERCALL_SETUP();
     418           0 :     fctx = funcctx->user_fctx;
     419             : 
     420           0 :     fctx[0] += 1;
     421           0 :     result = fctx[0];
     422             : 
     423           0 :     if (result <= fctx[1])
     424             :     {
     425             :         /* do when there is more left to send */
     426           0 :         SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
     427             :     }
     428             :     else
     429             :     {
     430             :         /* do when there is no more left */
     431           0 :         SRF_RETURN_DONE(funcctx);
     432             :     }
     433             : }
     434             : 
     435             : /*
     436             :  * Returns command progress information for the named command.
     437             :  */
     438             : Datum
     439           0 : pg_stat_get_progress_info(PG_FUNCTION_ARGS)
     440             : {
     441             : #define PG_STAT_GET_PROGRESS_COLS   PGSTAT_NUM_PROGRESS_PARAM + 3
     442           0 :     int         num_backends = pgstat_fetch_stat_numbackends();
     443             :     int         curr_backend;
     444           0 :     char       *cmd = text_to_cstring(PG_GETARG_TEXT_PP(0));
     445             :     ProgressCommandType cmdtype;
     446             :     TupleDesc   tupdesc;
     447             :     Tuplestorestate *tupstore;
     448           0 :     ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
     449             :     MemoryContext per_query_ctx;
     450             :     MemoryContext oldcontext;
     451             : 
     452             :     /* check to see if caller supports us returning a tuplestore */
     453           0 :     if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
     454           0 :         ereport(ERROR,
     455             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     456             :                  errmsg("set-valued function called in context that cannot accept a set")));
     457           0 :     if (!(rsinfo->allowedModes & SFRM_Materialize))
     458           0 :         ereport(ERROR,
     459             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     460             :                  errmsg("materialize mode required, but it is not " \
     461             :                         "allowed in this context")));
     462             : 
     463             :     /* Build a tuple descriptor for our result type */
     464           0 :     if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
     465           0 :         elog(ERROR, "return type must be a row type");
     466             : 
     467             :     /* Translate command name into command type code. */
     468           0 :     if (pg_strcasecmp(cmd, "VACUUM") == 0)
     469           0 :         cmdtype = PROGRESS_COMMAND_VACUUM;
     470             :     else
     471           0 :         ereport(ERROR,
     472             :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
     473             :                  errmsg("invalid command name: \"%s\"", cmd)));
     474             : 
     475           0 :     per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
     476           0 :     oldcontext = MemoryContextSwitchTo(per_query_ctx);
     477             : 
     478           0 :     tupstore = tuplestore_begin_heap(true, false, work_mem);
     479           0 :     rsinfo->returnMode = SFRM_Materialize;
     480           0 :     rsinfo->setResult = tupstore;
     481           0 :     rsinfo->setDesc = tupdesc;
     482           0 :     MemoryContextSwitchTo(oldcontext);
     483             : 
     484             :     /* 1-based index */
     485           0 :     for (curr_backend = 1; curr_backend <= num_backends; curr_backend++)
     486             :     {
     487             :         LocalPgBackendStatus *local_beentry;
     488             :         PgBackendStatus *beentry;
     489             :         Datum       values[PG_STAT_GET_PROGRESS_COLS];
     490             :         bool        nulls[PG_STAT_GET_PROGRESS_COLS];
     491             :         int         i;
     492             : 
     493           0 :         MemSet(values, 0, sizeof(values));
     494           0 :         MemSet(nulls, 0, sizeof(nulls));
     495             : 
     496           0 :         local_beentry = pgstat_fetch_stat_local_beentry(curr_backend);
     497             : 
     498           0 :         if (!local_beentry)
     499           0 :             continue;
     500             : 
     501           0 :         beentry = &local_beentry->backendStatus;
     502             : 
     503             :         /*
     504             :          * Report values for only those backends which are running the given
     505             :          * command.
     506             :          */
     507           0 :         if (!beentry || beentry->st_progress_command != cmdtype)
     508           0 :             continue;
     509             : 
     510             :         /* Value available to all callers */
     511           0 :         values[0] = Int32GetDatum(beentry->st_procpid);
     512           0 :         values[1] = ObjectIdGetDatum(beentry->st_databaseid);
     513             : 
     514             :         /* show rest of the values including relid only to role members */
     515           0 :         if (has_privs_of_role(GetUserId(), beentry->st_userid))
     516             :         {
     517           0 :             values[2] = ObjectIdGetDatum(beentry->st_progress_command_target);
     518           0 :             for (i = 0; i < PGSTAT_NUM_PROGRESS_PARAM; i++)
     519           0 :                 values[i + 3] = Int64GetDatum(beentry->st_progress_param[i]);
     520             :         }
     521             :         else
     522             :         {
     523           0 :             nulls[2] = true;
     524           0 :             for (i = 0; i < PGSTAT_NUM_PROGRESS_PARAM; i++)
     525           0 :                 nulls[i + 3] = true;
     526             :         }
     527             : 
     528           0 :         tuplestore_putvalues(tupstore, tupdesc, values, nulls);
     529             :     }
     530             : 
     531             :     /* clean up and return the tuplestore */
     532             :     tuplestore_donestoring(tupstore);
     533             : 
     534           0 :     return (Datum) 0;
     535             : }
     536             : 
     537             : /*
     538             :  * Returns activity of PG backends.
     539             :  */
     540             : Datum
     541           0 : pg_stat_get_activity(PG_FUNCTION_ARGS)
     542             : {
     543             : #define PG_STAT_GET_ACTIVITY_COLS   24
     544           0 :     int         num_backends = pgstat_fetch_stat_numbackends();
     545             :     int         curr_backend;
     546           0 :     int         pid = PG_ARGISNULL(0) ? -1 : PG_GETARG_INT32(0);
     547           0 :     ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
     548             :     TupleDesc   tupdesc;
     549             :     Tuplestorestate *tupstore;
     550             :     MemoryContext per_query_ctx;
     551             :     MemoryContext oldcontext;
     552             : 
     553             :     /* check to see if caller supports us returning a tuplestore */
     554           0 :     if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
     555           0 :         ereport(ERROR,
     556             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     557             :                  errmsg("set-valued function called in context that cannot accept a set")));
     558           0 :     if (!(rsinfo->allowedModes & SFRM_Materialize))
     559           0 :         ereport(ERROR,
     560             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     561             :                  errmsg("materialize mode required, but it is not " \
     562             :                         "allowed in this context")));
     563             : 
     564             :     /* Build a tuple descriptor for our result type */
     565           0 :     if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
     566           0 :         elog(ERROR, "return type must be a row type");
     567             : 
     568           0 :     per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
     569           0 :     oldcontext = MemoryContextSwitchTo(per_query_ctx);
     570             : 
     571           0 :     tupstore = tuplestore_begin_heap(true, false, work_mem);
     572           0 :     rsinfo->returnMode = SFRM_Materialize;
     573           0 :     rsinfo->setResult = tupstore;
     574           0 :     rsinfo->setDesc = tupdesc;
     575             : 
     576           0 :     MemoryContextSwitchTo(oldcontext);
     577             : 
     578             :     /* 1-based index */
     579           0 :     for (curr_backend = 1; curr_backend <= num_backends; curr_backend++)
     580             :     {
     581             :         /* for each row */
     582             :         Datum       values[PG_STAT_GET_ACTIVITY_COLS];
     583             :         bool        nulls[PG_STAT_GET_ACTIVITY_COLS];
     584             :         LocalPgBackendStatus *local_beentry;
     585             :         PgBackendStatus *beentry;
     586             :         PGPROC     *proc;
     587           0 :         const char *wait_event_type = NULL;
     588           0 :         const char *wait_event = NULL;
     589             : 
     590           0 :         MemSet(values, 0, sizeof(values));
     591           0 :         MemSet(nulls, 0, sizeof(nulls));
     592             : 
     593             :         /* Get the next one in the list */
     594           0 :         local_beentry = pgstat_fetch_stat_local_beentry(curr_backend);
     595           0 :         if (!local_beentry)
     596             :         {
     597             :             int         i;
     598             : 
     599             :             /* Ignore missing entries if looking for specific PID */
     600           0 :             if (pid != -1)
     601           0 :                 continue;
     602             : 
     603           0 :             for (i = 0; i < lengthof(nulls); i++)
     604           0 :                 nulls[i] = true;
     605             : 
     606           0 :             nulls[5] = false;
     607           0 :             values[5] = CStringGetTextDatum("<backend information not available>");
     608             : 
     609           0 :             tuplestore_putvalues(tupstore, tupdesc, values, nulls);
     610           0 :             continue;
     611             :         }
     612             : 
     613           0 :         beentry = &local_beentry->backendStatus;
     614             : 
     615             :         /* If looking for specific PID, ignore all the others */
     616           0 :         if (pid != -1 && beentry->st_procpid != pid)
     617           0 :             continue;
     618             : 
     619             :         /* Values available to all callers */
     620           0 :         if (beentry->st_databaseid != InvalidOid)
     621           0 :             values[0] = ObjectIdGetDatum(beentry->st_databaseid);
     622             :         else
     623           0 :             nulls[0] = true;
     624             : 
     625           0 :         values[1] = Int32GetDatum(beentry->st_procpid);
     626             : 
     627           0 :         if (beentry->st_userid != InvalidOid)
     628           0 :             values[2] = ObjectIdGetDatum(beentry->st_userid);
     629             :         else
     630           0 :             nulls[2] = true;
     631             : 
     632           0 :         if (beentry->st_appname)
     633           0 :             values[3] = CStringGetTextDatum(beentry->st_appname);
     634             :         else
     635           0 :             nulls[3] = true;
     636             : 
     637           0 :         if (TransactionIdIsValid(local_beentry->backend_xid))
     638           0 :             values[15] = TransactionIdGetDatum(local_beentry->backend_xid);
     639             :         else
     640           0 :             nulls[15] = true;
     641             : 
     642           0 :         if (TransactionIdIsValid(local_beentry->backend_xmin))
     643           0 :             values[16] = TransactionIdGetDatum(local_beentry->backend_xmin);
     644             :         else
     645           0 :             nulls[16] = true;
     646             : 
     647           0 :         if (beentry->st_ssl)
     648             :         {
     649           0 :             values[18] = BoolGetDatum(true);    /* ssl */
     650           0 :             values[19] = CStringGetTextDatum(beentry->st_sslstatus->ssl_version);
     651           0 :             values[20] = CStringGetTextDatum(beentry->st_sslstatus->ssl_cipher);
     652           0 :             values[21] = Int32GetDatum(beentry->st_sslstatus->ssl_bits);
     653           0 :             values[22] = BoolGetDatum(beentry->st_sslstatus->ssl_compression);
     654           0 :             values[23] = CStringGetTextDatum(beentry->st_sslstatus->ssl_clientdn);
     655             :         }
     656             :         else
     657             :         {
     658           0 :             values[18] = BoolGetDatum(false);   /* ssl */
     659           0 :             nulls[19] = nulls[20] = nulls[21] = nulls[22] = nulls[23] = true;
     660             :         }
     661             : 
     662             :         /* Values only available to role member or pg_read_all_stats */
     663           0 :         if (has_privs_of_role(GetUserId(), beentry->st_userid) ||
     664           0 :             is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_STATS))
     665           0 :         {
     666             :             SockAddr    zero_clientaddr;
     667             : 
     668           0 :             switch (beentry->st_state)
     669             :             {
     670             :                 case STATE_IDLE:
     671           0 :                     values[4] = CStringGetTextDatum("idle");
     672           0 :                     break;
     673             :                 case STATE_RUNNING:
     674           0 :                     values[4] = CStringGetTextDatum("active");
     675           0 :                     break;
     676             :                 case STATE_IDLEINTRANSACTION:
     677           0 :                     values[4] = CStringGetTextDatum("idle in transaction");
     678           0 :                     break;
     679             :                 case STATE_FASTPATH:
     680           0 :                     values[4] = CStringGetTextDatum("fastpath function call");
     681           0 :                     break;
     682             :                 case STATE_IDLEINTRANSACTION_ABORTED:
     683           0 :                     values[4] = CStringGetTextDatum("idle in transaction (aborted)");
     684           0 :                     break;
     685             :                 case STATE_DISABLED:
     686           0 :                     values[4] = CStringGetTextDatum("disabled");
     687           0 :                     break;
     688             :                 case STATE_UNDEFINED:
     689           0 :                     nulls[4] = true;
     690           0 :                     break;
     691             :             }
     692             : 
     693           0 :             values[5] = CStringGetTextDatum(beentry->st_activity);
     694             : 
     695           0 :             proc = BackendPidGetProc(beentry->st_procpid);
     696           0 :             if (proc != NULL)
     697             :             {
     698             :                 uint32      raw_wait_event;
     699             : 
     700           0 :                 raw_wait_event = UINT32_ACCESS_ONCE(proc->wait_event_info);
     701           0 :                 wait_event_type = pgstat_get_wait_event_type(raw_wait_event);
     702           0 :                 wait_event = pgstat_get_wait_event(raw_wait_event);
     703             : 
     704             :             }
     705           0 :             else if (beentry->st_backendType != B_BACKEND)
     706             :             {
     707             :                 /*
     708             :                  * For an auxiliary process, retrieve process info from
     709             :                  * AuxiliaryProcs stored in shared-memory.
     710             :                  */
     711           0 :                 proc = AuxiliaryPidGetProc(beentry->st_procpid);
     712             : 
     713           0 :                 if (proc != NULL)
     714             :                 {
     715             :                     uint32      raw_wait_event;
     716             : 
     717           0 :                     raw_wait_event =
     718             :                         UINT32_ACCESS_ONCE(proc->wait_event_info);
     719           0 :                     wait_event_type =
     720             :                         pgstat_get_wait_event_type(raw_wait_event);
     721           0 :                     wait_event = pgstat_get_wait_event(raw_wait_event);
     722             :                 }
     723             :             }
     724             : 
     725           0 :             if (wait_event_type)
     726           0 :                 values[6] = CStringGetTextDatum(wait_event_type);
     727             :             else
     728           0 :                 nulls[6] = true;
     729             : 
     730           0 :             if (wait_event)
     731           0 :                 values[7] = CStringGetTextDatum(wait_event);
     732             :             else
     733           0 :                 nulls[7] = true;
     734             : 
     735           0 :             if (beentry->st_xact_start_timestamp != 0)
     736           0 :                 values[8] = TimestampTzGetDatum(beentry->st_xact_start_timestamp);
     737             :             else
     738           0 :                 nulls[8] = true;
     739             : 
     740           0 :             if (beentry->st_activity_start_timestamp != 0)
     741           0 :                 values[9] = TimestampTzGetDatum(beentry->st_activity_start_timestamp);
     742             :             else
     743           0 :                 nulls[9] = true;
     744             : 
     745           0 :             if (beentry->st_proc_start_timestamp != 0)
     746           0 :                 values[10] = TimestampTzGetDatum(beentry->st_proc_start_timestamp);
     747             :             else
     748           0 :                 nulls[10] = true;
     749             : 
     750           0 :             if (beentry->st_state_start_timestamp != 0)
     751           0 :                 values[11] = TimestampTzGetDatum(beentry->st_state_start_timestamp);
     752             :             else
     753           0 :                 nulls[11] = true;
     754             : 
     755             :             /* A zeroed client addr means we don't know */
     756           0 :             memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
     757           0 :             if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
     758             :                        sizeof(zero_clientaddr)) == 0)
     759             :             {
     760           0 :                 nulls[12] = true;
     761           0 :                 nulls[13] = true;
     762           0 :                 nulls[14] = true;
     763             :             }
     764             :             else
     765             :             {
     766           0 :                 if (beentry->st_clientaddr.addr.ss_family == AF_INET
     767             : #ifdef HAVE_IPV6
     768           0 :                     || beentry->st_clientaddr.addr.ss_family == AF_INET6
     769             : #endif
     770             :                     )
     771           0 :                 {
     772             :                     char        remote_host[NI_MAXHOST];
     773             :                     char        remote_port[NI_MAXSERV];
     774             :                     int         ret;
     775             : 
     776           0 :                     remote_host[0] = '\0';
     777           0 :                     remote_port[0] = '\0';
     778           0 :                     ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
     779           0 :                                              beentry->st_clientaddr.salen,
     780             :                                              remote_host, sizeof(remote_host),
     781             :                                              remote_port, sizeof(remote_port),
     782             :                                              NI_NUMERICHOST | NI_NUMERICSERV);
     783           0 :                     if (ret == 0)
     784             :                     {
     785           0 :                         clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
     786           0 :                         values[12] = DirectFunctionCall1(inet_in,
     787             :                                                          CStringGetDatum(remote_host));
     788           0 :                         if (beentry->st_clienthostname &&
     789           0 :                             beentry->st_clienthostname[0])
     790           0 :                             values[13] = CStringGetTextDatum(beentry->st_clienthostname);
     791             :                         else
     792           0 :                             nulls[13] = true;
     793           0 :                         values[14] = Int32GetDatum(atoi(remote_port));
     794             :                     }
     795             :                     else
     796             :                     {
     797           0 :                         nulls[12] = true;
     798           0 :                         nulls[13] = true;
     799           0 :                         nulls[14] = true;
     800             :                     }
     801             :                 }
     802           0 :                 else if (beentry->st_clientaddr.addr.ss_family == AF_UNIX)
     803             :                 {
     804             :                     /*
     805             :                      * Unix sockets always reports NULL for host and -1 for
     806             :                      * port, so it's possible to tell the difference to
     807             :                      * connections we have no permissions to view, or with
     808             :                      * errors.
     809             :                      */
     810           0 :                     nulls[12] = true;
     811           0 :                     nulls[13] = true;
     812           0 :                     values[14] = DatumGetInt32(-1);
     813             :                 }
     814             :                 else
     815             :                 {
     816             :                     /* Unknown address type, should never happen */
     817           0 :                     nulls[12] = true;
     818           0 :                     nulls[13] = true;
     819           0 :                     nulls[14] = true;
     820             :                 }
     821             :             }
     822             :             /* Add backend type */
     823           0 :             values[17] =
     824           0 :                 CStringGetTextDatum(pgstat_get_backend_desc(beentry->st_backendType));
     825             :         }
     826             :         else
     827             :         {
     828             :             /* No permissions to view data about this session */
     829           0 :             values[5] = CStringGetTextDatum("<insufficient privilege>");
     830           0 :             nulls[4] = true;
     831           0 :             nulls[6] = true;
     832           0 :             nulls[7] = true;
     833           0 :             nulls[8] = true;
     834           0 :             nulls[9] = true;
     835           0 :             nulls[10] = true;
     836           0 :             nulls[11] = true;
     837           0 :             nulls[12] = true;
     838           0 :             nulls[13] = true;
     839           0 :             nulls[14] = true;
     840           0 :             nulls[17] = true;
     841             :         }
     842             : 
     843           0 :         tuplestore_putvalues(tupstore, tupdesc, values, nulls);
     844             : 
     845             :         /* If only a single backend was requested, and we found it, break. */
     846           0 :         if (pid != -1)
     847           0 :             break;
     848             :     }
     849             : 
     850             :     /* clean up and return the tuplestore */
     851             :     tuplestore_donestoring(tupstore);
     852             : 
     853           0 :     return (Datum) 0;
     854             : }
     855             : 
     856             : 
     857             : Datum
     858           0 : pg_backend_pid(PG_FUNCTION_ARGS)
     859             : {
     860           0 :     PG_RETURN_INT32(MyProcPid);
     861             : }
     862             : 
     863             : 
     864             : Datum
     865           0 : pg_stat_get_backend_pid(PG_FUNCTION_ARGS)
     866             : {
     867           0 :     int32       beid = PG_GETARG_INT32(0);
     868             :     PgBackendStatus *beentry;
     869             : 
     870           0 :     if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
     871           0 :         PG_RETURN_NULL();
     872             : 
     873           0 :     PG_RETURN_INT32(beentry->st_procpid);
     874             : }
     875             : 
     876             : 
     877             : Datum
     878           0 : pg_stat_get_backend_dbid(PG_FUNCTION_ARGS)
     879             : {
     880           0 :     int32       beid = PG_GETARG_INT32(0);
     881             :     PgBackendStatus *beentry;
     882             : 
     883           0 :     if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
     884           0 :         PG_RETURN_NULL();
     885             : 
     886           0 :     PG_RETURN_OID(beentry->st_databaseid);
     887             : }
     888             : 
     889             : 
     890             : Datum
     891           0 : pg_stat_get_backend_userid(PG_FUNCTION_ARGS)
     892             : {
     893           0 :     int32       beid = PG_GETARG_INT32(0);
     894             :     PgBackendStatus *beentry;
     895             : 
     896           0 :     if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
     897           0 :         PG_RETURN_NULL();
     898             : 
     899           0 :     PG_RETURN_OID(beentry->st_userid);
     900             : }
     901             : 
     902             : 
     903             : Datum
     904           0 : pg_stat_get_backend_activity(PG_FUNCTION_ARGS)
     905             : {
     906           0 :     int32       beid = PG_GETARG_INT32(0);
     907             :     PgBackendStatus *beentry;
     908             :     const char *activity;
     909             : 
     910           0 :     if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
     911           0 :         activity = "<backend information not available>";
     912           0 :     else if (!has_privs_of_role(GetUserId(), beentry->st_userid))
     913           0 :         activity = "<insufficient privilege>";
     914           0 :     else if (*(beentry->st_activity) == '\0')
     915           0 :         activity = "<command string not enabled>";
     916             :     else
     917           0 :         activity = beentry->st_activity;
     918             : 
     919           0 :     PG_RETURN_TEXT_P(cstring_to_text(activity));
     920             : }
     921             : 
     922             : Datum
     923           0 : pg_stat_get_backend_wait_event_type(PG_FUNCTION_ARGS)
     924             : {
     925           0 :     int32       beid = PG_GETARG_INT32(0);
     926             :     PgBackendStatus *beentry;
     927             :     PGPROC     *proc;
     928           0 :     const char *wait_event_type = NULL;
     929             : 
     930           0 :     if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
     931           0 :         wait_event_type = "<backend information not available>";
     932           0 :     else if (!has_privs_of_role(GetUserId(), beentry->st_userid))
     933           0 :         wait_event_type = "<insufficient privilege>";
     934           0 :     else if ((proc = BackendPidGetProc(beentry->st_procpid)) != NULL)
     935           0 :         wait_event_type = pgstat_get_wait_event_type(proc->wait_event_info);
     936             : 
     937           0 :     if (!wait_event_type)
     938           0 :         PG_RETURN_NULL();
     939             : 
     940           0 :     PG_RETURN_TEXT_P(cstring_to_text(wait_event_type));
     941             : }
     942             : 
     943             : Datum
     944           0 : pg_stat_get_backend_wait_event(PG_FUNCTION_ARGS)
     945             : {
     946           0 :     int32       beid = PG_GETARG_INT32(0);
     947             :     PgBackendStatus *beentry;
     948             :     PGPROC     *proc;
     949           0 :     const char *wait_event = NULL;
     950             : 
     951           0 :     if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
     952           0 :         wait_event = "<backend information not available>";
     953           0 :     else if (!has_privs_of_role(GetUserId(), beentry->st_userid))
     954           0 :         wait_event = "<insufficient privilege>";
     955           0 :     else if ((proc = BackendPidGetProc(beentry->st_procpid)) != NULL)
     956           0 :         wait_event = pgstat_get_wait_event(proc->wait_event_info);
     957             : 
     958           0 :     if (!wait_event)
     959           0 :         PG_RETURN_NULL();
     960             : 
     961           0 :     PG_RETURN_TEXT_P(cstring_to_text(wait_event));
     962             : }
     963             : 
     964             : 
     965             : Datum
     966           0 : pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS)
     967             : {
     968           0 :     int32       beid = PG_GETARG_INT32(0);
     969             :     TimestampTz result;
     970             :     PgBackendStatus *beentry;
     971             : 
     972           0 :     if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
     973           0 :         PG_RETURN_NULL();
     974             : 
     975           0 :     if (!has_privs_of_role(GetUserId(), beentry->st_userid))
     976           0 :         PG_RETURN_NULL();
     977             : 
     978           0 :     result = beentry->st_activity_start_timestamp;
     979             : 
     980             :     /*
     981             :      * No time recorded for start of current query -- this is the case if the
     982             :      * user hasn't enabled query-level stats collection.
     983             :      */
     984           0 :     if (result == 0)
     985           0 :         PG_RETURN_NULL();
     986             : 
     987           0 :     PG_RETURN_TIMESTAMPTZ(result);
     988             : }
     989             : 
     990             : 
     991             : Datum
     992           0 : pg_stat_get_backend_xact_start(PG_FUNCTION_ARGS)
     993             : {
     994           0 :     int32       beid = PG_GETARG_INT32(0);
     995             :     TimestampTz result;
     996             :     PgBackendStatus *beentry;
     997             : 
     998           0 :     if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
     999           0 :         PG_RETURN_NULL();
    1000             : 
    1001           0 :     if (!has_privs_of_role(GetUserId(), beentry->st_userid))
    1002           0 :         PG_RETURN_NULL();
    1003             : 
    1004           0 :     result = beentry->st_xact_start_timestamp;
    1005             : 
    1006           0 :     if (result == 0)            /* not in a transaction */
    1007           0 :         PG_RETURN_NULL();
    1008             : 
    1009           0 :     PG_RETURN_TIMESTAMPTZ(result);
    1010             : }
    1011             : 
    1012             : 
    1013             : Datum
    1014           0 : pg_stat_get_backend_start(PG_FUNCTION_ARGS)
    1015             : {
    1016           0 :     int32       beid = PG_GETARG_INT32(0);
    1017             :     TimestampTz result;
    1018             :     PgBackendStatus *beentry;
    1019             : 
    1020           0 :     if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
    1021           0 :         PG_RETURN_NULL();
    1022             : 
    1023           0 :     if (!has_privs_of_role(GetUserId(), beentry->st_userid))
    1024           0 :         PG_RETURN_NULL();
    1025             : 
    1026           0 :     result = beentry->st_proc_start_timestamp;
    1027             : 
    1028           0 :     if (result == 0)            /* probably can't happen? */
    1029           0 :         PG_RETURN_NULL();
    1030             : 
    1031           0 :     PG_RETURN_TIMESTAMPTZ(result);
    1032             : }
    1033             : 
    1034             : 
    1035             : Datum
    1036           0 : pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
    1037             : {
    1038           0 :     int32       beid = PG_GETARG_INT32(0);
    1039             :     PgBackendStatus *beentry;
    1040             :     SockAddr    zero_clientaddr;
    1041             :     char        remote_host[NI_MAXHOST];
    1042             :     int         ret;
    1043             : 
    1044           0 :     if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
    1045           0 :         PG_RETURN_NULL();
    1046             : 
    1047           0 :     if (!has_privs_of_role(GetUserId(), beentry->st_userid))
    1048           0 :         PG_RETURN_NULL();
    1049             : 
    1050             :     /* A zeroed client addr means we don't know */
    1051           0 :     memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
    1052           0 :     if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
    1053             :                sizeof(zero_clientaddr)) == 0)
    1054           0 :         PG_RETURN_NULL();
    1055             : 
    1056           0 :     switch (beentry->st_clientaddr.addr.ss_family)
    1057             :     {
    1058             :         case AF_INET:
    1059             : #ifdef HAVE_IPV6
    1060             :         case AF_INET6:
    1061             : #endif
    1062           0 :             break;
    1063             :         default:
    1064           0 :             PG_RETURN_NULL();
    1065             :     }
    1066             : 
    1067           0 :     remote_host[0] = '\0';
    1068           0 :     ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
    1069           0 :                              beentry->st_clientaddr.salen,
    1070             :                              remote_host, sizeof(remote_host),
    1071             :                              NULL, 0,
    1072             :                              NI_NUMERICHOST | NI_NUMERICSERV);
    1073           0 :     if (ret != 0)
    1074           0 :         PG_RETURN_NULL();
    1075             : 
    1076           0 :     clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
    1077             : 
    1078           0 :     PG_RETURN_INET_P(DirectFunctionCall1(inet_in,
    1079             :                                          CStringGetDatum(remote_host)));
    1080             : }
    1081             : 
    1082             : Datum
    1083           0 : pg_stat_get_backend_client_port(PG_FUNCTION_ARGS)
    1084             : {
    1085           0 :     int32       beid = PG_GETARG_INT32(0);
    1086             :     PgBackendStatus *beentry;
    1087             :     SockAddr    zero_clientaddr;
    1088             :     char        remote_port[NI_MAXSERV];
    1089             :     int         ret;
    1090             : 
    1091           0 :     if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
    1092           0 :         PG_RETURN_NULL();
    1093             : 
    1094           0 :     if (!has_privs_of_role(GetUserId(), beentry->st_userid))
    1095           0 :         PG_RETURN_NULL();
    1096             : 
    1097             :     /* A zeroed client addr means we don't know */
    1098           0 :     memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
    1099           0 :     if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
    1100             :                sizeof(zero_clientaddr)) == 0)
    1101           0 :         PG_RETURN_NULL();
    1102             : 
    1103           0 :     switch (beentry->st_clientaddr.addr.ss_family)
    1104             :     {
    1105             :         case AF_INET:
    1106             : #ifdef HAVE_IPV6
    1107             :         case AF_INET6:
    1108             : #endif
    1109           0 :             break;
    1110             :         case AF_UNIX:
    1111           0 :             PG_RETURN_INT32(-1);
    1112             :         default:
    1113           0 :             PG_RETURN_NULL();
    1114             :     }
    1115             : 
    1116           0 :     remote_port[0] = '\0';
    1117           0 :     ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
    1118           0 :                              beentry->st_clientaddr.salen,
    1119             :                              NULL, 0,
    1120             :                              remote_port, sizeof(remote_port),
    1121             :                              NI_NUMERICHOST | NI_NUMERICSERV);
    1122           0 :     if (ret != 0)
    1123           0 :         PG_RETURN_NULL();
    1124             : 
    1125           0 :     PG_RETURN_DATUM(DirectFunctionCall1(int4in,
    1126             :                                         CStringGetDatum(remote_port)));
    1127             : }
    1128             : 
    1129             : 
    1130             : Datum
    1131           0 : pg_stat_get_db_numbackends(PG_FUNCTION_ARGS)
    1132             : {
    1133           0 :     Oid         dbid = PG_GETARG_OID(0);
    1134             :     int32       result;
    1135           0 :     int         tot_backends = pgstat_fetch_stat_numbackends();
    1136             :     int         beid;
    1137             : 
    1138           0 :     result = 0;
    1139           0 :     for (beid = 1; beid <= tot_backends; beid++)
    1140             :     {
    1141           0 :         PgBackendStatus *beentry = pgstat_fetch_stat_beentry(beid);
    1142             : 
    1143           0 :         if (beentry && beentry->st_databaseid == dbid)
    1144           0 :             result++;
    1145             :     }
    1146             : 
    1147           0 :     PG_RETURN_INT32(result);
    1148             : }
    1149             : 
    1150             : 
    1151             : Datum
    1152           0 : pg_stat_get_db_xact_commit(PG_FUNCTION_ARGS)
    1153             : {
    1154           0 :     Oid         dbid = PG_GETARG_OID(0);
    1155             :     int64       result;
    1156             :     PgStat_StatDBEntry *dbentry;
    1157             : 
    1158           0 :     if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
    1159           0 :         result = 0;
    1160             :     else
    1161           0 :         result = (int64) (dbentry->n_xact_commit);
    1162             : 
    1163           0 :     PG_RETURN_INT64(result);
    1164             : }
    1165             : 
    1166             : 
    1167             : Datum
    1168           0 : pg_stat_get_db_xact_rollback(PG_FUNCTION_ARGS)
    1169             : {
    1170           0 :     Oid         dbid = PG_GETARG_OID(0);
    1171             :     int64       result;
    1172             :     PgStat_StatDBEntry *dbentry;
    1173             : 
    1174           0 :     if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
    1175           0 :         result = 0;
    1176             :     else
    1177           0 :         result = (int64) (dbentry->n_xact_rollback);
    1178             : 
    1179           0 :     PG_RETURN_INT64(result);
    1180             : }
    1181             : 
    1182             : 
    1183             : Datum
    1184           0 : pg_stat_get_db_blocks_fetched(PG_FUNCTION_ARGS)
    1185             : {
    1186           0 :     Oid         dbid = PG_GETARG_OID(0);
    1187             :     int64       result;
    1188             :     PgStat_StatDBEntry *dbentry;
    1189             : 
    1190           0 :     if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
    1191           0 :         result = 0;
    1192             :     else
    1193           0 :         result = (int64) (dbentry->n_blocks_fetched);
    1194             : 
    1195           0 :     PG_RETURN_INT64(result);
    1196             : }
    1197             : 
    1198             : 
    1199             : Datum
    1200           0 : pg_stat_get_db_blocks_hit(PG_FUNCTION_ARGS)
    1201             : {
    1202           0 :     Oid         dbid = PG_GETARG_OID(0);
    1203             :     int64       result;
    1204             :     PgStat_StatDBEntry *dbentry;
    1205             : 
    1206           0 :     if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
    1207           0 :         result = 0;
    1208             :     else
    1209           0 :         result = (int64) (dbentry->n_blocks_hit);
    1210             : 
    1211           0 :     PG_RETURN_INT64(result);
    1212             : }
    1213             : 
    1214             : 
    1215             : Datum
    1216           0 : pg_stat_get_db_tuples_returned(PG_FUNCTION_ARGS)
    1217             : {
    1218           0 :     Oid         dbid = PG_GETARG_OID(0);
    1219             :     int64       result;
    1220             :     PgStat_StatDBEntry *dbentry;
    1221             : 
    1222           0 :     if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
    1223           0 :         result = 0;
    1224             :     else
    1225           0 :         result = (int64) (dbentry->n_tuples_returned);
    1226             : 
    1227           0 :     PG_RETURN_INT64(result);
    1228             : }
    1229             : 
    1230             : 
    1231             : Datum
    1232           0 : pg_stat_get_db_tuples_fetched(PG_FUNCTION_ARGS)
    1233             : {
    1234           0 :     Oid         dbid = PG_GETARG_OID(0);
    1235             :     int64       result;
    1236             :     PgStat_StatDBEntry *dbentry;
    1237             : 
    1238           0 :     if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
    1239           0 :         result = 0;
    1240             :     else
    1241           0 :         result = (int64) (dbentry->n_tuples_fetched);
    1242             : 
    1243           0 :     PG_RETURN_INT64(result);
    1244             : }
    1245             : 
    1246             : 
    1247             : Datum
    1248           0 : pg_stat_get_db_tuples_inserted(PG_FUNCTION_ARGS)
    1249             : {
    1250           0 :     Oid         dbid = PG_GETARG_OID(0);
    1251             :     int64       result;
    1252             :     PgStat_StatDBEntry *dbentry;
    1253             : 
    1254           0 :     if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
    1255           0 :         result = 0;
    1256             :     else
    1257           0 :         result = (int64) (dbentry->n_tuples_inserted);
    1258             : 
    1259           0 :     PG_RETURN_INT64(result);
    1260             : }
    1261             : 
    1262             : 
    1263             : Datum
    1264           0 : pg_stat_get_db_tuples_updated(PG_FUNCTION_ARGS)
    1265             : {
    1266           0 :     Oid         dbid = PG_GETARG_OID(0);
    1267             :     int64       result;
    1268             :     PgStat_StatDBEntry *dbentry;
    1269             : 
    1270           0 :     if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
    1271           0 :         result = 0;
    1272             :     else
    1273           0 :         result = (int64) (dbentry->n_tuples_updated);
    1274             : 
    1275           0 :     PG_RETURN_INT64(result);
    1276             : }
    1277             : 
    1278             : 
    1279             : Datum
    1280           0 : pg_stat_get_db_tuples_deleted(PG_FUNCTION_ARGS)
    1281             : {
    1282           0 :     Oid         dbid = PG_GETARG_OID(0);
    1283             :     int64       result;
    1284             :     PgStat_StatDBEntry *dbentry;
    1285             : 
    1286           0 :     if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
    1287           0 :         result = 0;
    1288             :     else
    1289           0 :         result = (int64) (dbentry->n_tuples_deleted);
    1290             : 
    1291           0 :     PG_RETURN_INT64(result);
    1292             : }
    1293             : 
    1294             : Datum
    1295           0 : pg_stat_get_db_stat_reset_time(PG_FUNCTION_ARGS)
    1296             : {
    1297           0 :     Oid         dbid = PG_GETARG_OID(0);
    1298             :     TimestampTz result;
    1299             :     PgStat_StatDBEntry *dbentry;
    1300             : 
    1301           0 :     if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
    1302           0 :         result = 0;
    1303             :     else
    1304           0 :         result = dbentry->stat_reset_timestamp;
    1305             : 
    1306           0 :     if (result == 0)
    1307           0 :         PG_RETURN_NULL();
    1308             :     else
    1309           0 :         PG_RETURN_TIMESTAMPTZ(result);
    1310             : }
    1311             : 
    1312             : Datum
    1313           0 : pg_stat_get_db_temp_files(PG_FUNCTION_ARGS)
    1314             : {
    1315           0 :     Oid         dbid = PG_GETARG_OID(0);
    1316             :     int64       result;
    1317             :     PgStat_StatDBEntry *dbentry;
    1318             : 
    1319           0 :     if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
    1320           0 :         result = 0;
    1321             :     else
    1322           0 :         result = dbentry->n_temp_files;
    1323             : 
    1324           0 :     PG_RETURN_INT64(result);
    1325             : }
    1326             : 
    1327             : 
    1328             : Datum
    1329           0 : pg_stat_get_db_temp_bytes(PG_FUNCTION_ARGS)
    1330             : {
    1331           0 :     Oid         dbid = PG_GETARG_OID(0);
    1332             :     int64       result;
    1333             :     PgStat_StatDBEntry *dbentry;
    1334             : 
    1335           0 :     if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
    1336           0 :         result = 0;
    1337             :     else
    1338           0 :         result = dbentry->n_temp_bytes;
    1339             : 
    1340           0 :     PG_RETURN_INT64(result);
    1341             : }
    1342             : 
    1343             : Datum
    1344           0 : pg_stat_get_db_conflict_tablespace(PG_FUNCTION_ARGS)
    1345             : {
    1346           0 :     Oid         dbid = PG_GETARG_OID(0);
    1347             :     int64       result;
    1348             :     PgStat_StatDBEntry *dbentry;
    1349             : 
    1350           0 :     if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
    1351           0 :         result = 0;
    1352             :     else
    1353           0 :         result = (int64) (dbentry->n_conflict_tablespace);
    1354             : 
    1355           0 :     PG_RETURN_INT64(result);
    1356             : }
    1357             : 
    1358             : Datum
    1359           0 : pg_stat_get_db_conflict_lock(PG_FUNCTION_ARGS)
    1360             : {
    1361           0 :     Oid         dbid = PG_GETARG_OID(0);
    1362             :     int64       result;
    1363             :     PgStat_StatDBEntry *dbentry;
    1364             : 
    1365           0 :     if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
    1366           0 :         result = 0;
    1367             :     else
    1368           0 :         result = (int64) (dbentry->n_conflict_lock);
    1369             : 
    1370           0 :     PG_RETURN_INT64(result);
    1371             : }
    1372             : 
    1373             : Datum
    1374           0 : pg_stat_get_db_conflict_snapshot(PG_FUNCTION_ARGS)
    1375             : {
    1376           0 :     Oid         dbid = PG_GETARG_OID(0);
    1377             :     int64       result;
    1378             :     PgStat_StatDBEntry *dbentry;
    1379             : 
    1380           0 :     if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
    1381           0 :         result = 0;
    1382             :     else
    1383           0 :         result = (int64) (dbentry->n_conflict_snapshot);
    1384             : 
    1385           0 :     PG_RETURN_INT64(result);
    1386             : }
    1387             : 
    1388             : Datum
    1389           0 : pg_stat_get_db_conflict_bufferpin(PG_FUNCTION_ARGS)
    1390             : {
    1391           0 :     Oid         dbid = PG_GETARG_OID(0);
    1392             :     int64       result;
    1393             :     PgStat_StatDBEntry *dbentry;
    1394             : 
    1395           0 :     if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
    1396           0 :         result = 0;
    1397             :     else
    1398           0 :         result = (int64) (dbentry->n_conflict_bufferpin);
    1399             : 
    1400           0 :     PG_RETURN_INT64(result);
    1401             : }
    1402             : 
    1403             : Datum
    1404           0 : pg_stat_get_db_conflict_startup_deadlock(PG_FUNCTION_ARGS)
    1405             : {
    1406           0 :     Oid         dbid = PG_GETARG_OID(0);
    1407             :     int64       result;
    1408             :     PgStat_StatDBEntry *dbentry;
    1409             : 
    1410           0 :     if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
    1411           0 :         result = 0;
    1412             :     else
    1413           0 :         result = (int64) (dbentry->n_conflict_startup_deadlock);
    1414             : 
    1415           0 :     PG_RETURN_INT64(result);
    1416             : }
    1417             : 
    1418             : Datum
    1419           0 : pg_stat_get_db_conflict_all(PG_FUNCTION_ARGS)
    1420             : {
    1421           0 :     Oid         dbid = PG_GETARG_OID(0);
    1422             :     int64       result;
    1423             :     PgStat_StatDBEntry *dbentry;
    1424             : 
    1425           0 :     if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
    1426           0 :         result = 0;
    1427             :     else
    1428           0 :         result = (int64) (
    1429           0 :                           dbentry->n_conflict_tablespace +
    1430           0 :                           dbentry->n_conflict_lock +
    1431           0 :                           dbentry->n_conflict_snapshot +
    1432           0 :                           dbentry->n_conflict_bufferpin +
    1433           0 :                           dbentry->n_conflict_startup_deadlock);
    1434             : 
    1435           0 :     PG_RETURN_INT64(result);
    1436             : }
    1437             : 
    1438             : Datum
    1439           0 : pg_stat_get_db_deadlocks(PG_FUNCTION_ARGS)
    1440             : {
    1441           0 :     Oid         dbid = PG_GETARG_OID(0);
    1442             :     int64       result;
    1443             :     PgStat_StatDBEntry *dbentry;
    1444             : 
    1445           0 :     if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
    1446           0 :         result = 0;
    1447             :     else
    1448           0 :         result = (int64) (dbentry->n_deadlocks);
    1449             : 
    1450           0 :     PG_RETURN_INT64(result);
    1451             : }
    1452             : 
    1453             : Datum
    1454           0 : pg_stat_get_db_blk_read_time(PG_FUNCTION_ARGS)
    1455             : {
    1456           0 :     Oid         dbid = PG_GETARG_OID(0);
    1457             :     double      result;
    1458             :     PgStat_StatDBEntry *dbentry;
    1459             : 
    1460             :     /* convert counter from microsec to millisec for display */
    1461           0 :     if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
    1462           0 :         result = 0;
    1463             :     else
    1464           0 :         result = ((double) dbentry->n_block_read_time) / 1000.0;
    1465             : 
    1466           0 :     PG_RETURN_FLOAT8(result);
    1467             : }
    1468             : 
    1469             : Datum
    1470           0 : pg_stat_get_db_blk_write_time(PG_FUNCTION_ARGS)
    1471             : {
    1472           0 :     Oid         dbid = PG_GETARG_OID(0);
    1473             :     double      result;
    1474             :     PgStat_StatDBEntry *dbentry;
    1475             : 
    1476             :     /* convert counter from microsec to millisec for display */
    1477           0 :     if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
    1478           0 :         result = 0;
    1479             :     else
    1480           0 :         result = ((double) dbentry->n_block_write_time) / 1000.0;
    1481             : 
    1482           0 :     PG_RETURN_FLOAT8(result);
    1483             : }
    1484             : 
    1485             : Datum
    1486           0 : pg_stat_get_bgwriter_timed_checkpoints(PG_FUNCTION_ARGS)
    1487             : {
    1488           0 :     PG_RETURN_INT64(pgstat_fetch_global()->timed_checkpoints);
    1489             : }
    1490             : 
    1491             : Datum
    1492           0 : pg_stat_get_bgwriter_requested_checkpoints(PG_FUNCTION_ARGS)
    1493             : {
    1494           0 :     PG_RETURN_INT64(pgstat_fetch_global()->requested_checkpoints);
    1495             : }
    1496             : 
    1497             : Datum
    1498           0 : pg_stat_get_bgwriter_buf_written_checkpoints(PG_FUNCTION_ARGS)
    1499             : {
    1500           0 :     PG_RETURN_INT64(pgstat_fetch_global()->buf_written_checkpoints);
    1501             : }
    1502             : 
    1503             : Datum
    1504           0 : pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS)
    1505             : {
    1506           0 :     PG_RETURN_INT64(pgstat_fetch_global()->buf_written_clean);
    1507             : }
    1508             : 
    1509             : Datum
    1510           0 : pg_stat_get_bgwriter_maxwritten_clean(PG_FUNCTION_ARGS)
    1511             : {
    1512           0 :     PG_RETURN_INT64(pgstat_fetch_global()->maxwritten_clean);
    1513             : }
    1514             : 
    1515             : Datum
    1516           0 : pg_stat_get_checkpoint_write_time(PG_FUNCTION_ARGS)
    1517             : {
    1518             :     /* time is already in msec, just convert to double for presentation */
    1519           0 :     PG_RETURN_FLOAT8((double) pgstat_fetch_global()->checkpoint_write_time);
    1520             : }
    1521             : 
    1522             : Datum
    1523           0 : pg_stat_get_checkpoint_sync_time(PG_FUNCTION_ARGS)
    1524             : {
    1525             :     /* time is already in msec, just convert to double for presentation */
    1526           0 :     PG_RETURN_FLOAT8((double) pgstat_fetch_global()->checkpoint_sync_time);
    1527             : }
    1528             : 
    1529             : Datum
    1530           0 : pg_stat_get_bgwriter_stat_reset_time(PG_FUNCTION_ARGS)
    1531             : {
    1532           0 :     PG_RETURN_TIMESTAMPTZ(pgstat_fetch_global()->stat_reset_timestamp);
    1533             : }
    1534             : 
    1535             : Datum
    1536           0 : pg_stat_get_buf_written_backend(PG_FUNCTION_ARGS)
    1537             : {
    1538           0 :     PG_RETURN_INT64(pgstat_fetch_global()->buf_written_backend);
    1539             : }
    1540             : 
    1541             : Datum
    1542           0 : pg_stat_get_buf_fsync_backend(PG_FUNCTION_ARGS)
    1543             : {
    1544           0 :     PG_RETURN_INT64(pgstat_fetch_global()->buf_fsync_backend);
    1545             : }
    1546             : 
    1547             : Datum
    1548           0 : pg_stat_get_buf_alloc(PG_FUNCTION_ARGS)
    1549             : {
    1550           0 :     PG_RETURN_INT64(pgstat_fetch_global()->buf_alloc);
    1551             : }
    1552             : 
    1553             : Datum
    1554           0 : pg_stat_get_xact_numscans(PG_FUNCTION_ARGS)
    1555             : {
    1556           0 :     Oid         relid = PG_GETARG_OID(0);
    1557             :     int64       result;
    1558             :     PgStat_TableStatus *tabentry;
    1559             : 
    1560           0 :     if ((tabentry = find_tabstat_entry(relid)) == NULL)
    1561           0 :         result = 0;
    1562             :     else
    1563           0 :         result = (int64) (tabentry->t_counts.t_numscans);
    1564             : 
    1565           0 :     PG_RETURN_INT64(result);
    1566             : }
    1567             : 
    1568             : Datum
    1569           0 : pg_stat_get_xact_tuples_returned(PG_FUNCTION_ARGS)
    1570             : {
    1571           0 :     Oid         relid = PG_GETARG_OID(0);
    1572             :     int64       result;
    1573             :     PgStat_TableStatus *tabentry;
    1574             : 
    1575           0 :     if ((tabentry = find_tabstat_entry(relid)) == NULL)
    1576           0 :         result = 0;
    1577             :     else
    1578           0 :         result = (int64) (tabentry->t_counts.t_tuples_returned);
    1579             : 
    1580           0 :     PG_RETURN_INT64(result);
    1581             : }
    1582             : 
    1583             : Datum
    1584           0 : pg_stat_get_xact_tuples_fetched(PG_FUNCTION_ARGS)
    1585             : {
    1586           0 :     Oid         relid = PG_GETARG_OID(0);
    1587             :     int64       result;
    1588             :     PgStat_TableStatus *tabentry;
    1589             : 
    1590           0 :     if ((tabentry = find_tabstat_entry(relid)) == NULL)
    1591           0 :         result = 0;
    1592             :     else
    1593           0 :         result = (int64) (tabentry->t_counts.t_tuples_fetched);
    1594             : 
    1595           0 :     PG_RETURN_INT64(result);
    1596             : }
    1597             : 
    1598             : Datum
    1599           0 : pg_stat_get_xact_tuples_inserted(PG_FUNCTION_ARGS)
    1600             : {
    1601           0 :     Oid         relid = PG_GETARG_OID(0);
    1602             :     int64       result;
    1603             :     PgStat_TableStatus *tabentry;
    1604             :     PgStat_TableXactStatus *trans;
    1605             : 
    1606           0 :     if ((tabentry = find_tabstat_entry(relid)) == NULL)
    1607           0 :         result = 0;
    1608             :     else
    1609             :     {
    1610           0 :         result = tabentry->t_counts.t_tuples_inserted;
    1611             :         /* live subtransactions' counts aren't in t_tuples_inserted yet */
    1612           0 :         for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
    1613           0 :             result += trans->tuples_inserted;
    1614             :     }
    1615             : 
    1616           0 :     PG_RETURN_INT64(result);
    1617             : }
    1618             : 
    1619             : Datum
    1620           0 : pg_stat_get_xact_tuples_updated(PG_FUNCTION_ARGS)
    1621             : {
    1622           0 :     Oid         relid = PG_GETARG_OID(0);
    1623             :     int64       result;
    1624             :     PgStat_TableStatus *tabentry;
    1625             :     PgStat_TableXactStatus *trans;
    1626             : 
    1627           0 :     if ((tabentry = find_tabstat_entry(relid)) == NULL)
    1628           0 :         result = 0;
    1629             :     else
    1630             :     {
    1631           0 :         result = tabentry->t_counts.t_tuples_updated;
    1632             :         /* live subtransactions' counts aren't in t_tuples_updated yet */
    1633           0 :         for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
    1634           0 :             result += trans->tuples_updated;
    1635             :     }
    1636             : 
    1637           0 :     PG_RETURN_INT64(result);
    1638             : }
    1639             : 
    1640             : Datum
    1641           0 : pg_stat_get_xact_tuples_deleted(PG_FUNCTION_ARGS)
    1642             : {
    1643           0 :     Oid         relid = PG_GETARG_OID(0);
    1644             :     int64       result;
    1645             :     PgStat_TableStatus *tabentry;
    1646             :     PgStat_TableXactStatus *trans;
    1647             : 
    1648           0 :     if ((tabentry = find_tabstat_entry(relid)) == NULL)
    1649           0 :         result = 0;
    1650             :     else
    1651             :     {
    1652           0 :         result = tabentry->t_counts.t_tuples_deleted;
    1653             :         /* live subtransactions' counts aren't in t_tuples_deleted yet */
    1654           0 :         for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
    1655           0 :             result += trans->tuples_deleted;
    1656             :     }
    1657             : 
    1658           0 :     PG_RETURN_INT64(result);
    1659             : }
    1660             : 
    1661             : Datum
    1662           0 : pg_stat_get_xact_tuples_hot_updated(PG_FUNCTION_ARGS)
    1663             : {
    1664           0 :     Oid         relid = PG_GETARG_OID(0);
    1665             :     int64       result;
    1666             :     PgStat_TableStatus *tabentry;
    1667             : 
    1668           0 :     if ((tabentry = find_tabstat_entry(relid)) == NULL)
    1669           0 :         result = 0;
    1670             :     else
    1671           0 :         result = (int64) (tabentry->t_counts.t_tuples_hot_updated);
    1672             : 
    1673           0 :     PG_RETURN_INT64(result);
    1674             : }
    1675             : 
    1676             : Datum
    1677           0 : pg_stat_get_xact_blocks_fetched(PG_FUNCTION_ARGS)
    1678             : {
    1679           0 :     Oid         relid = PG_GETARG_OID(0);
    1680             :     int64       result;
    1681             :     PgStat_TableStatus *tabentry;
    1682             : 
    1683           0 :     if ((tabentry = find_tabstat_entry(relid)) == NULL)
    1684           0 :         result = 0;
    1685             :     else
    1686           0 :         result = (int64) (tabentry->t_counts.t_blocks_fetched);
    1687             : 
    1688           0 :     PG_RETURN_INT64(result);
    1689             : }
    1690             : 
    1691             : Datum
    1692           0 : pg_stat_get_xact_blocks_hit(PG_FUNCTION_ARGS)
    1693             : {
    1694           0 :     Oid         relid = PG_GETARG_OID(0);
    1695             :     int64       result;
    1696             :     PgStat_TableStatus *tabentry;
    1697             : 
    1698           0 :     if ((tabentry = find_tabstat_entry(relid)) == NULL)
    1699           0 :         result = 0;
    1700             :     else
    1701           0 :         result = (int64) (tabentry->t_counts.t_blocks_hit);
    1702             : 
    1703           0 :     PG_RETURN_INT64(result);
    1704             : }
    1705             : 
    1706             : Datum
    1707           0 : pg_stat_get_xact_function_calls(PG_FUNCTION_ARGS)
    1708             : {
    1709           0 :     Oid         funcid = PG_GETARG_OID(0);
    1710             :     PgStat_BackendFunctionEntry *funcentry;
    1711             : 
    1712           0 :     if ((funcentry = find_funcstat_entry(funcid)) == NULL)
    1713           0 :         PG_RETURN_NULL();
    1714           0 :     PG_RETURN_INT64(funcentry->f_counts.f_numcalls);
    1715             : }
    1716             : 
    1717             : Datum
    1718           0 : pg_stat_get_xact_function_total_time(PG_FUNCTION_ARGS)
    1719             : {
    1720           0 :     Oid         funcid = PG_GETARG_OID(0);
    1721             :     PgStat_BackendFunctionEntry *funcentry;
    1722             : 
    1723           0 :     if ((funcentry = find_funcstat_entry(funcid)) == NULL)
    1724           0 :         PG_RETURN_NULL();
    1725           0 :     PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(funcentry->f_counts.f_total_time));
    1726             : }
    1727             : 
    1728             : Datum
    1729           0 : pg_stat_get_xact_function_self_time(PG_FUNCTION_ARGS)
    1730             : {
    1731           0 :     Oid         funcid = PG_GETARG_OID(0);
    1732             :     PgStat_BackendFunctionEntry *funcentry;
    1733             : 
    1734           0 :     if ((funcentry = find_funcstat_entry(funcid)) == NULL)
    1735           0 :         PG_RETURN_NULL();
    1736           0 :     PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(funcentry->f_counts.f_self_time));
    1737             : }
    1738             : 
    1739             : 
    1740             : /* Get the timestamp of the current statistics snapshot */
    1741             : Datum
    1742           5 : pg_stat_get_snapshot_timestamp(PG_FUNCTION_ARGS)
    1743             : {
    1744           5 :     PG_RETURN_TIMESTAMPTZ(pgstat_fetch_global()->stats_timestamp);
    1745             : }
    1746             : 
    1747             : /* Discard the active statistics snapshot */
    1748             : Datum
    1749           2 : pg_stat_clear_snapshot(PG_FUNCTION_ARGS)
    1750             : {
    1751           2 :     pgstat_clear_snapshot();
    1752             : 
    1753           2 :     PG_RETURN_VOID();
    1754             : }
    1755             : 
    1756             : 
    1757             : /* Reset all counters for the current database */
    1758             : Datum
    1759           0 : pg_stat_reset(PG_FUNCTION_ARGS)
    1760             : {
    1761           0 :     pgstat_reset_counters();
    1762             : 
    1763           0 :     PG_RETURN_VOID();
    1764             : }
    1765             : 
    1766             : /* Reset some shared cluster-wide counters */
    1767             : Datum
    1768           0 : pg_stat_reset_shared(PG_FUNCTION_ARGS)
    1769             : {
    1770           0 :     char       *target = text_to_cstring(PG_GETARG_TEXT_PP(0));
    1771             : 
    1772           0 :     pgstat_reset_shared_counters(target);
    1773             : 
    1774           0 :     PG_RETURN_VOID();
    1775             : }
    1776             : 
    1777             : /* Reset a single counter in the current database */
    1778             : Datum
    1779           0 : pg_stat_reset_single_table_counters(PG_FUNCTION_ARGS)
    1780             : {
    1781           0 :     Oid         taboid = PG_GETARG_OID(0);
    1782             : 
    1783           0 :     pgstat_reset_single_counter(taboid, RESET_TABLE);
    1784             : 
    1785           0 :     PG_RETURN_VOID();
    1786             : }
    1787             : 
    1788             : Datum
    1789           0 : pg_stat_reset_single_function_counters(PG_FUNCTION_ARGS)
    1790             : {
    1791           0 :     Oid         funcoid = PG_GETARG_OID(0);
    1792             : 
    1793           0 :     pgstat_reset_single_counter(funcoid, RESET_FUNCTION);
    1794             : 
    1795           0 :     PG_RETURN_VOID();
    1796             : }
    1797             : 
    1798             : Datum
    1799           0 : pg_stat_get_archiver(PG_FUNCTION_ARGS)
    1800             : {
    1801             :     TupleDesc   tupdesc;
    1802             :     Datum       values[7];
    1803             :     bool        nulls[7];
    1804             :     PgStat_ArchiverStats *archiver_stats;
    1805             : 
    1806             :     /* Initialise values and NULL flags arrays */
    1807           0 :     MemSet(values, 0, sizeof(values));
    1808           0 :     MemSet(nulls, 0, sizeof(nulls));
    1809             : 
    1810             :     /* Initialise attributes information in the tuple descriptor */
    1811           0 :     tupdesc = CreateTemplateTupleDesc(7, false);
    1812           0 :     TupleDescInitEntry(tupdesc, (AttrNumber) 1, "archived_count",
    1813             :                        INT8OID, -1, 0);
    1814           0 :     TupleDescInitEntry(tupdesc, (AttrNumber) 2, "last_archived_wal",
    1815             :                        TEXTOID, -1, 0);
    1816           0 :     TupleDescInitEntry(tupdesc, (AttrNumber) 3, "last_archived_time",
    1817             :                        TIMESTAMPTZOID, -1, 0);
    1818           0 :     TupleDescInitEntry(tupdesc, (AttrNumber) 4, "failed_count",
    1819             :                        INT8OID, -1, 0);
    1820           0 :     TupleDescInitEntry(tupdesc, (AttrNumber) 5, "last_failed_wal",
    1821             :                        TEXTOID, -1, 0);
    1822           0 :     TupleDescInitEntry(tupdesc, (AttrNumber) 6, "last_failed_time",
    1823             :                        TIMESTAMPTZOID, -1, 0);
    1824           0 :     TupleDescInitEntry(tupdesc, (AttrNumber) 7, "stats_reset",
    1825             :                        TIMESTAMPTZOID, -1, 0);
    1826             : 
    1827           0 :     BlessTupleDesc(tupdesc);
    1828             : 
    1829             :     /* Get statistics about the archiver process */
    1830           0 :     archiver_stats = pgstat_fetch_stat_archiver();
    1831             : 
    1832             :     /* Fill values and NULLs */
    1833           0 :     values[0] = Int64GetDatum(archiver_stats->archived_count);
    1834           0 :     if (*(archiver_stats->last_archived_wal) == '\0')
    1835           0 :         nulls[1] = true;
    1836             :     else
    1837           0 :         values[1] = CStringGetTextDatum(archiver_stats->last_archived_wal);
    1838             : 
    1839           0 :     if (archiver_stats->last_archived_timestamp == 0)
    1840           0 :         nulls[2] = true;
    1841             :     else
    1842           0 :         values[2] = TimestampTzGetDatum(archiver_stats->last_archived_timestamp);
    1843             : 
    1844           0 :     values[3] = Int64GetDatum(archiver_stats->failed_count);
    1845           0 :     if (*(archiver_stats->last_failed_wal) == '\0')
    1846           0 :         nulls[4] = true;
    1847             :     else
    1848           0 :         values[4] = CStringGetTextDatum(archiver_stats->last_failed_wal);
    1849             : 
    1850           0 :     if (archiver_stats->last_failed_timestamp == 0)
    1851           0 :         nulls[5] = true;
    1852             :     else
    1853           0 :         values[5] = TimestampTzGetDatum(archiver_stats->last_failed_timestamp);
    1854             : 
    1855           0 :     if (archiver_stats->stat_reset_timestamp == 0)
    1856           0 :         nulls[6] = true;
    1857             :     else
    1858           0 :         values[6] = TimestampTzGetDatum(archiver_stats->stat_reset_timestamp);
    1859             : 
    1860             :     /* Returns the record as Datum */
    1861           0 :     PG_RETURN_DATUM(HeapTupleGetDatum(
    1862             :                                       heap_form_tuple(tupdesc, values, nulls)));
    1863             : }

Generated by: LCOV version 1.11