LCOV - code coverage report
Current view: top level - src/test/modules/test_custom_stats - test_custom_fixed_stats.c (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 100.0 % 56 56
Test Date: 2026-07-25 22:15:46 Functions: 100.0 % 11 11
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 100.0 % 2 2

             Branch data     Line data    Source code
       1                 :             : /*--------------------------------------------------------------------------
       2                 :             :  *
       3                 :             :  * test_custom_fixed_stats.c
       4                 :             :  *      Test module for fixed-sized custom pgstats
       5                 :             :  *
       6                 :             :  * Copyright (c) 2025-2026, PostgreSQL Global Development Group
       7                 :             :  *
       8                 :             :  * IDENTIFICATION
       9                 :             :  *      src/test/modules/test_custom_stats/test_custom_fixed_stats.c
      10                 :             :  *
      11                 :             :  * -------------------------------------------------------------------------
      12                 :             :  */
      13                 :             : 
      14                 :             : #include "postgres.h"
      15                 :             : 
      16                 :             : #include "access/htup_details.h"
      17                 :             : #include "funcapi.h"
      18                 :             : #include "pgstat.h"
      19                 :             : #include "utils/builtins.h"
      20                 :             : #include "utils/pgstat_internal.h"
      21                 :             : #include "utils/timestamp.h"
      22                 :             : 
      23                 :           3 : PG_MODULE_MAGIC_EXT(
      24                 :             :                     .name = "test_custom_fixed_stats",
      25                 :             :                     .version = PG_VERSION
      26                 :             : );
      27                 :             : 
      28                 :             : /* Fixed-amount custom statistics entry */
      29                 :             : typedef struct PgStat_StatCustomFixedEntry
      30                 :             : {
      31                 :             :     PgStat_Counter numcalls;    /* # of times update function called */
      32                 :             :     TimestampTz stat_reset_timestamp;
      33                 :             : } PgStat_StatCustomFixedEntry;
      34                 :             : 
      35                 :             : typedef struct PgStatShared_CustomFixedEntry
      36                 :             : {
      37                 :             :     LWLock      lock;           /* protects counters */
      38                 :             :     uint32      changecount;    /* for atomic reads */
      39                 :             :     PgStat_StatCustomFixedEntry stats;  /* current counters */
      40                 :             :     PgStat_StatCustomFixedEntry reset_offset;   /* reset baseline */
      41                 :             : } PgStatShared_CustomFixedEntry;
      42                 :             : 
      43                 :             : /* Callbacks for fixed-amount statistics */
      44                 :             : static void test_custom_stats_fixed_init_shmem_cb(void *stats);
      45                 :             : static void test_custom_stats_fixed_reset_all_cb(TimestampTz ts);
      46                 :             : static void test_custom_stats_fixed_snapshot_cb(void);
      47                 :             : 
      48                 :             : static const PgStat_KindInfo custom_stats = {
      49                 :             :     .name = "test_custom_fixed_stats",
      50                 :             :     .fixed_amount = true,       /* exactly one entry */
      51                 :             :     .write_to_file = true,      /* persist to stats file */
      52                 :             : 
      53                 :             :     .shared_size = sizeof(PgStatShared_CustomFixedEntry),
      54                 :             :     .shared_data_off = offsetof(PgStatShared_CustomFixedEntry, stats),
      55                 :             :     .shared_data_len = sizeof(((PgStatShared_CustomFixedEntry *) 0)->stats),
      56                 :             : 
      57                 :             :     .init_shmem_cb = test_custom_stats_fixed_init_shmem_cb,
      58                 :             :     .reset_all_cb = test_custom_stats_fixed_reset_all_cb,
      59                 :             :     .snapshot_cb = test_custom_stats_fixed_snapshot_cb,
      60                 :             : };
      61                 :             : 
      62                 :             : /*
      63                 :             :  * Kind ID for test_custom_fixed_stats.
      64                 :             :  */
      65                 :             : #define PGSTAT_KIND_TEST_CUSTOM_FIXED_STATS 26
      66                 :             : 
      67                 :             : /*--------------------------------------------------------------------------
      68                 :             :  * Module initialization
      69                 :             :  *--------------------------------------------------------------------------
      70                 :             :  */
      71                 :             : 
      72                 :             : void
      73                 :           3 : _PG_init(void)
      74                 :             : {
      75                 :             :     /* Register custom statistics kind */
      76                 :           3 :     pgstat_register_kind(PGSTAT_KIND_TEST_CUSTOM_FIXED_STATS, &custom_stats);
      77                 :           3 : }
      78                 :             : 
      79                 :             : /*
      80                 :             :  * test_custom_stats_fixed_init_shmem_cb
      81                 :             :  *      Initialize shared memory structure
      82                 :             :  */
      83                 :             : static void
      84                 :           3 : test_custom_stats_fixed_init_shmem_cb(void *stats)
      85                 :             : {
      86                 :           3 :     PgStatShared_CustomFixedEntry *stats_shmem =
      87                 :             :         (PgStatShared_CustomFixedEntry *) stats;
      88                 :             : 
      89                 :           3 :     LWLockInitialize(&stats_shmem->lock, LWTRANCHE_PGSTATS_DATA);
      90                 :           3 : }
      91                 :             : 
      92                 :             : /*
      93                 :             :  * test_custom_stats_fixed_reset_all_cb
      94                 :             :  *      Reset the fixed-sized stats
      95                 :             :  */
      96                 :             : static void
      97                 :           2 : test_custom_stats_fixed_reset_all_cb(TimestampTz ts)
      98                 :             : {
      99                 :             :     PgStatShared_CustomFixedEntry *stats_shmem =
     100                 :           2 :         pgstat_get_custom_shmem_data(PGSTAT_KIND_TEST_CUSTOM_FIXED_STATS);
     101                 :             : 
     102                 :             :     /* see explanation above PgStatShared_Archiver for the reset protocol */
     103                 :           2 :     LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
     104                 :           2 :     pgstat_copy_changecounted_stats(&stats_shmem->reset_offset,
     105                 :           2 :                                     &stats_shmem->stats,
     106                 :             :                                     sizeof(stats_shmem->stats),
     107                 :             :                                     &stats_shmem->changecount);
     108                 :           2 :     stats_shmem->stats.stat_reset_timestamp = ts;
     109                 :           2 :     LWLockRelease(&stats_shmem->lock);
     110                 :           2 : }
     111                 :             : 
     112                 :             : /*
     113                 :             :  * test_custom_stats_fixed_snapshot_cb
     114                 :             :  *      Copy current stats to snapshot area
     115                 :             :  */
     116                 :             : static void
     117                 :           4 : test_custom_stats_fixed_snapshot_cb(void)
     118                 :             : {
     119                 :             :     PgStatShared_CustomFixedEntry *stats_shmem =
     120                 :           4 :         pgstat_get_custom_shmem_data(PGSTAT_KIND_TEST_CUSTOM_FIXED_STATS);
     121                 :             :     PgStat_StatCustomFixedEntry *stat_snap =
     122                 :           4 :         pgstat_get_custom_snapshot_data(PGSTAT_KIND_TEST_CUSTOM_FIXED_STATS);
     123                 :           4 :     PgStat_StatCustomFixedEntry *reset_offset = &stats_shmem->reset_offset;
     124                 :             :     PgStat_StatCustomFixedEntry reset;
     125                 :             : 
     126                 :           4 :     pgstat_copy_changecounted_stats(stat_snap,
     127                 :           4 :                                     &stats_shmem->stats,
     128                 :             :                                     sizeof(stats_shmem->stats),
     129                 :             :                                     &stats_shmem->changecount);
     130                 :             : 
     131                 :           4 :     LWLockAcquire(&stats_shmem->lock, LW_SHARED);
     132                 :           4 :     memcpy(&reset, reset_offset, sizeof(stats_shmem->stats));
     133                 :           4 :     LWLockRelease(&stats_shmem->lock);
     134                 :             : 
     135                 :             :     /* Apply reset offsets */
     136                 :             : #define FIXED_COMP(fld) stat_snap->fld -= reset.fld;
     137                 :           4 :     FIXED_COMP(numcalls);
     138                 :             : #undef FIXED_COMP
     139                 :           4 : }
     140                 :             : 
     141                 :             : /*--------------------------------------------------------------------------
     142                 :             :  * SQL-callable functions
     143                 :             :  *--------------------------------------------------------------------------
     144                 :             :  */
     145                 :             : 
     146                 :             : /*
     147                 :             :  * test_custom_stats_fixed_update
     148                 :             :  *      Increment call counter
     149                 :             :  */
     150                 :           7 : PG_FUNCTION_INFO_V1(test_custom_stats_fixed_update);
     151                 :             : Datum
     152                 :           6 : test_custom_stats_fixed_update(PG_FUNCTION_ARGS)
     153                 :             : {
     154                 :             :     PgStatShared_CustomFixedEntry *stats_shmem;
     155                 :             : 
     156                 :           6 :     stats_shmem = pgstat_get_custom_shmem_data(PGSTAT_KIND_TEST_CUSTOM_FIXED_STATS);
     157                 :             : 
     158                 :           6 :     LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
     159                 :             : 
     160                 :           6 :     pgstat_begin_changecount_write(&stats_shmem->changecount);
     161                 :           6 :     stats_shmem->stats.numcalls++;
     162                 :           6 :     pgstat_end_changecount_write(&stats_shmem->changecount);
     163                 :             : 
     164                 :           6 :     LWLockRelease(&stats_shmem->lock);
     165                 :             : 
     166                 :           6 :     PG_RETURN_VOID();
     167                 :             : }
     168                 :             : 
     169                 :             : /*
     170                 :             :  * test_custom_stats_fixed_reset
     171                 :             :  *      Reset statistics by calling pgstat system
     172                 :             :  */
     173                 :           2 : PG_FUNCTION_INFO_V1(test_custom_stats_fixed_reset);
     174                 :             : Datum
     175                 :           1 : test_custom_stats_fixed_reset(PG_FUNCTION_ARGS)
     176                 :             : {
     177                 :           1 :     pgstat_reset_of_kind(PGSTAT_KIND_TEST_CUSTOM_FIXED_STATS);
     178                 :             : 
     179                 :           1 :     PG_RETURN_VOID();
     180                 :             : }
     181                 :             : 
     182                 :             : /*
     183                 :             :  * test_custom_stats_fixed_report
     184                 :             :  *      Return current counter values
     185                 :             :  */
     186                 :           4 : PG_FUNCTION_INFO_V1(test_custom_stats_fixed_report);
     187                 :             : Datum
     188                 :           3 : test_custom_stats_fixed_report(PG_FUNCTION_ARGS)
     189                 :             : {
     190                 :             :     TupleDesc   tupdesc;
     191                 :           3 :     Datum       values[2] = {0};
     192                 :           3 :     bool        nulls[2] = {false};
     193                 :             :     PgStat_StatCustomFixedEntry *stats;
     194                 :             : 
     195                 :             :     /* Take snapshot (applies reset offsets) */
     196                 :           3 :     pgstat_snapshot_fixed(PGSTAT_KIND_TEST_CUSTOM_FIXED_STATS);
     197                 :           3 :     stats = pgstat_get_custom_snapshot_data(PGSTAT_KIND_TEST_CUSTOM_FIXED_STATS);
     198                 :             : 
     199                 :             :     /* Build return tuple */
     200                 :           3 :     tupdesc = CreateTemplateTupleDesc(2);
     201                 :           3 :     TupleDescInitEntry(tupdesc, (AttrNumber) 1, "numcalls",
     202                 :             :                        INT8OID, -1, 0);
     203                 :           3 :     TupleDescInitEntry(tupdesc, (AttrNumber) 2, "stats_reset",
     204                 :             :                        TIMESTAMPTZOID, -1, 0);
     205                 :           3 :     TupleDescFinalize(tupdesc);
     206                 :           3 :     BlessTupleDesc(tupdesc);
     207                 :             : 
     208                 :           3 :     values[0] = Int64GetDatum(stats->numcalls);
     209                 :             : 
     210                 :             :     /* Handle uninitialized timestamp (no reset yet) */
     211         [ +  + ]:           3 :     if (stats->stat_reset_timestamp == 0)
     212                 :             :     {
     213                 :           1 :         nulls[1] = true;
     214                 :             :     }
     215                 :             :     else
     216                 :             :     {
     217                 :           2 :         values[1] = TimestampTzGetDatum(stats->stat_reset_timestamp);
     218                 :             :     }
     219                 :             : 
     220                 :             :     /* Return as tuple */
     221                 :           3 :     PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));
     222                 :             : }
        

Generated by: LCOV version 2.0-1