LCOV - code coverage report
Current view: top level - src/backend/utils/misc - pg_controldata.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 93.3 % 120 112
Test Date: 2026-03-11 22:14:46 Functions: 100.0 % 4 4
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * pg_controldata.c
       4              :  *
       5              :  * Routines to expose the contents of the control data file via
       6              :  * a set of SQL functions.
       7              :  *
       8              :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       9              :  * Portions Copyright (c) 1994, Regents of the University of California
      10              :  *
      11              :  * IDENTIFICATION
      12              :  *    src/backend/utils/misc/pg_controldata.c
      13              :  *-------------------------------------------------------------------------
      14              :  */
      15              : 
      16              : #include "postgres.h"
      17              : 
      18              : #include "access/htup_details.h"
      19              : #include "access/transam.h"
      20              : #include "access/xlog.h"
      21              : #include "access/xlog_internal.h"
      22              : #include "catalog/pg_control.h"
      23              : #include "common/controldata_utils.h"
      24              : #include "funcapi.h"
      25              : #include "miscadmin.h"
      26              : #include "storage/lwlock.h"
      27              : #include "utils/builtins.h"
      28              : #include "utils/pg_lsn.h"
      29              : #include "utils/timestamp.h"
      30              : 
      31              : Datum
      32           15 : pg_control_system(PG_FUNCTION_ARGS)
      33              : {
      34              :     Datum       values[4];
      35              :     bool        nulls[4];
      36              :     TupleDesc   tupdesc;
      37              :     HeapTuple   htup;
      38              :     ControlFileData *ControlFile;
      39              :     bool        crc_ok;
      40              : 
      41           15 :     if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
      42            0 :         elog(ERROR, "return type must be a row type");
      43              : 
      44              :     /* read the control file */
      45           15 :     LWLockAcquire(ControlFileLock, LW_SHARED);
      46           15 :     ControlFile = get_controlfile(DataDir, &crc_ok);
      47           15 :     LWLockRelease(ControlFileLock);
      48           15 :     if (!crc_ok)
      49            0 :         ereport(ERROR,
      50              :                 (errmsg("calculated CRC checksum does not match value stored in file")));
      51              : 
      52           15 :     values[0] = Int32GetDatum(ControlFile->pg_control_version);
      53           15 :     nulls[0] = false;
      54              : 
      55           15 :     values[1] = Int32GetDatum(ControlFile->catalog_version_no);
      56           15 :     nulls[1] = false;
      57              : 
      58           15 :     values[2] = Int64GetDatum(ControlFile->system_identifier);
      59           15 :     nulls[2] = false;
      60              : 
      61           15 :     values[3] = TimestampTzGetDatum(time_t_to_timestamptz(ControlFile->time));
      62           15 :     nulls[3] = false;
      63              : 
      64           15 :     htup = heap_form_tuple(tupdesc, values, nulls);
      65              : 
      66           15 :     PG_RETURN_DATUM(HeapTupleGetDatum(htup));
      67              : }
      68              : 
      69              : Datum
      70            9 : pg_control_checkpoint(PG_FUNCTION_ARGS)
      71              : {
      72              :     Datum       values[18];
      73              :     bool        nulls[18];
      74              :     TupleDesc   tupdesc;
      75              :     HeapTuple   htup;
      76              :     ControlFileData *ControlFile;
      77              :     XLogSegNo   segno;
      78              :     char        xlogfilename[MAXFNAMELEN];
      79              :     bool        crc_ok;
      80              : 
      81            9 :     if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
      82            0 :         elog(ERROR, "return type must be a row type");
      83              : 
      84              :     /* Read the control file. */
      85            9 :     LWLockAcquire(ControlFileLock, LW_SHARED);
      86            9 :     ControlFile = get_controlfile(DataDir, &crc_ok);
      87            9 :     LWLockRelease(ControlFileLock);
      88            9 :     if (!crc_ok)
      89            0 :         ereport(ERROR,
      90              :                 (errmsg("calculated CRC checksum does not match value stored in file")));
      91              : 
      92              :     /*
      93              :      * Calculate name of the WAL file containing the latest checkpoint's REDO
      94              :      * start point.
      95              :      */
      96            9 :     XLByteToSeg(ControlFile->checkPointCopy.redo, segno, wal_segment_size);
      97            9 :     XLogFileName(xlogfilename, ControlFile->checkPointCopy.ThisTimeLineID,
      98              :                  segno, wal_segment_size);
      99              : 
     100              :     /* Populate the values and null arrays */
     101            9 :     values[0] = LSNGetDatum(ControlFile->checkPoint);
     102            9 :     nulls[0] = false;
     103              : 
     104            9 :     values[1] = LSNGetDatum(ControlFile->checkPointCopy.redo);
     105            9 :     nulls[1] = false;
     106              : 
     107            9 :     values[2] = CStringGetTextDatum(xlogfilename);
     108            9 :     nulls[2] = false;
     109              : 
     110            9 :     values[3] = Int32GetDatum(ControlFile->checkPointCopy.ThisTimeLineID);
     111            9 :     nulls[3] = false;
     112              : 
     113            9 :     values[4] = Int32GetDatum(ControlFile->checkPointCopy.PrevTimeLineID);
     114            9 :     nulls[4] = false;
     115              : 
     116            9 :     values[5] = BoolGetDatum(ControlFile->checkPointCopy.fullPageWrites);
     117            9 :     nulls[5] = false;
     118              : 
     119            9 :     values[6] = CStringGetTextDatum(psprintf("%u:%u",
     120              :                                              EpochFromFullTransactionId(ControlFile->checkPointCopy.nextXid),
     121              :                                              XidFromFullTransactionId(ControlFile->checkPointCopy.nextXid)));
     122            9 :     nulls[6] = false;
     123              : 
     124            9 :     values[7] = ObjectIdGetDatum(ControlFile->checkPointCopy.nextOid);
     125            9 :     nulls[7] = false;
     126              : 
     127            9 :     values[8] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMulti);
     128            9 :     nulls[8] = false;
     129              : 
     130            9 :     values[9] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMultiOffset);
     131            9 :     nulls[9] = false;
     132              : 
     133            9 :     values[10] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestXid);
     134            9 :     nulls[10] = false;
     135              : 
     136            9 :     values[11] = ObjectIdGetDatum(ControlFile->checkPointCopy.oldestXidDB);
     137            9 :     nulls[11] = false;
     138              : 
     139            9 :     values[12] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestActiveXid);
     140            9 :     nulls[12] = false;
     141              : 
     142            9 :     values[13] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestMulti);
     143            9 :     nulls[13] = false;
     144              : 
     145            9 :     values[14] = ObjectIdGetDatum(ControlFile->checkPointCopy.oldestMultiDB);
     146            9 :     nulls[14] = false;
     147              : 
     148            9 :     values[15] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestCommitTsXid);
     149            9 :     nulls[15] = false;
     150              : 
     151            9 :     values[16] = TransactionIdGetDatum(ControlFile->checkPointCopy.newestCommitTsXid);
     152            9 :     nulls[16] = false;
     153              : 
     154            9 :     values[17] = TimestampTzGetDatum(time_t_to_timestamptz(ControlFile->checkPointCopy.time));
     155            9 :     nulls[17] = false;
     156              : 
     157            9 :     htup = heap_form_tuple(tupdesc, values, nulls);
     158              : 
     159            9 :     PG_RETURN_DATUM(HeapTupleGetDatum(htup));
     160              : }
     161              : 
     162              : Datum
     163            3 : pg_control_recovery(PG_FUNCTION_ARGS)
     164              : {
     165              :     Datum       values[5];
     166              :     bool        nulls[5];
     167              :     TupleDesc   tupdesc;
     168              :     HeapTuple   htup;
     169              :     ControlFileData *ControlFile;
     170              :     bool        crc_ok;
     171              : 
     172            3 :     if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
     173            0 :         elog(ERROR, "return type must be a row type");
     174              : 
     175              :     /* read the control file */
     176            3 :     LWLockAcquire(ControlFileLock, LW_SHARED);
     177            3 :     ControlFile = get_controlfile(DataDir, &crc_ok);
     178            3 :     LWLockRelease(ControlFileLock);
     179            3 :     if (!crc_ok)
     180            0 :         ereport(ERROR,
     181              :                 (errmsg("calculated CRC checksum does not match value stored in file")));
     182              : 
     183            3 :     values[0] = LSNGetDatum(ControlFile->minRecoveryPoint);
     184            3 :     nulls[0] = false;
     185              : 
     186            3 :     values[1] = Int32GetDatum(ControlFile->minRecoveryPointTLI);
     187            3 :     nulls[1] = false;
     188              : 
     189            3 :     values[2] = LSNGetDatum(ControlFile->backupStartPoint);
     190            3 :     nulls[2] = false;
     191              : 
     192            3 :     values[3] = LSNGetDatum(ControlFile->backupEndPoint);
     193            3 :     nulls[3] = false;
     194              : 
     195            3 :     values[4] = BoolGetDatum(ControlFile->backupEndRequired);
     196            3 :     nulls[4] = false;
     197              : 
     198            3 :     htup = heap_form_tuple(tupdesc, values, nulls);
     199              : 
     200            3 :     PG_RETURN_DATUM(HeapTupleGetDatum(htup));
     201              : }
     202              : 
     203              : Datum
     204            4 : pg_control_init(PG_FUNCTION_ARGS)
     205              : {
     206              :     Datum       values[12];
     207              :     bool        nulls[12];
     208              :     TupleDesc   tupdesc;
     209              :     HeapTuple   htup;
     210              :     ControlFileData *ControlFile;
     211              :     bool        crc_ok;
     212              : 
     213            4 :     if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
     214            0 :         elog(ERROR, "return type must be a row type");
     215              : 
     216              :     /* read the control file */
     217            4 :     LWLockAcquire(ControlFileLock, LW_SHARED);
     218            4 :     ControlFile = get_controlfile(DataDir, &crc_ok);
     219            4 :     LWLockRelease(ControlFileLock);
     220            4 :     if (!crc_ok)
     221            0 :         ereport(ERROR,
     222              :                 (errmsg("calculated CRC checksum does not match value stored in file")));
     223              : 
     224            4 :     values[0] = Int32GetDatum(ControlFile->maxAlign);
     225            4 :     nulls[0] = false;
     226              : 
     227            4 :     values[1] = Int32GetDatum(ControlFile->blcksz);
     228            4 :     nulls[1] = false;
     229              : 
     230            4 :     values[2] = Int32GetDatum(ControlFile->relseg_size);
     231            4 :     nulls[2] = false;
     232              : 
     233            4 :     values[3] = Int32GetDatum(ControlFile->xlog_blcksz);
     234            4 :     nulls[3] = false;
     235              : 
     236            4 :     values[4] = Int32GetDatum(ControlFile->xlog_seg_size);
     237            4 :     nulls[4] = false;
     238              : 
     239            4 :     values[5] = Int32GetDatum(ControlFile->nameDataLen);
     240            4 :     nulls[5] = false;
     241              : 
     242            4 :     values[6] = Int32GetDatum(ControlFile->indexMaxKeys);
     243            4 :     nulls[6] = false;
     244              : 
     245            4 :     values[7] = Int32GetDatum(ControlFile->toast_max_chunk_size);
     246            4 :     nulls[7] = false;
     247              : 
     248            4 :     values[8] = Int32GetDatum(ControlFile->loblksize);
     249            4 :     nulls[8] = false;
     250              : 
     251            4 :     values[9] = BoolGetDatum(ControlFile->float8ByVal);
     252            4 :     nulls[9] = false;
     253              : 
     254            4 :     values[10] = Int32GetDatum(ControlFile->data_checksum_version);
     255            4 :     nulls[10] = false;
     256              : 
     257            4 :     values[11] = BoolGetDatum(ControlFile->default_char_signedness);
     258            4 :     nulls[11] = false;
     259              : 
     260            4 :     htup = heap_form_tuple(tupdesc, values, nulls);
     261              : 
     262            4 :     PG_RETURN_DATUM(HeapTupleGetDatum(htup));
     263              : }
        

Generated by: LCOV version 2.0-1