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

Generated by: LCOV version 1.13