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-04-07 14:16:30 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           16 : 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           16 :     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           16 :     LWLockAcquire(ControlFileLock, LW_SHARED);
      46           16 :     ControlFile = get_controlfile(DataDir, &crc_ok);
      47           16 :     LWLockRelease(ControlFileLock);
      48           16 :     if (!crc_ok)
      49            0 :         ereport(ERROR,
      50              :                 (errmsg("calculated CRC checksum does not match value stored in file")));
      51              : 
      52           16 :     values[0] = Int32GetDatum(ControlFile->pg_control_version);
      53           16 :     nulls[0] = false;
      54              : 
      55           16 :     values[1] = Int32GetDatum(ControlFile->catalog_version_no);
      56           16 :     nulls[1] = false;
      57              : 
      58           16 :     values[2] = Int64GetDatum(ControlFile->system_identifier);
      59           16 :     nulls[2] = false;
      60              : 
      61           16 :     values[3] = TimestampTzGetDatum(time_t_to_timestamptz(ControlFile->time));
      62           16 :     nulls[3] = false;
      63              : 
      64           16 :     htup = heap_form_tuple(tupdesc, values, nulls);
      65              : 
      66           16 :     PG_RETURN_DATUM(HeapTupleGetDatum(htup));
      67              : }
      68              : 
      69              : Datum
      70           10 : 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           10 :     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           10 :     LWLockAcquire(ControlFileLock, LW_SHARED);
      86           10 :     ControlFile = get_controlfile(DataDir, &crc_ok);
      87           10 :     LWLockRelease(ControlFileLock);
      88           10 :     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           10 :     XLByteToSeg(ControlFile->checkPointCopy.redo, segno, wal_segment_size);
      97           10 :     XLogFileName(xlogfilename, ControlFile->checkPointCopy.ThisTimeLineID,
      98              :                  segno, wal_segment_size);
      99              : 
     100              :     /* Populate the values and null arrays */
     101           10 :     values[0] = LSNGetDatum(ControlFile->checkPoint);
     102           10 :     nulls[0] = false;
     103              : 
     104           10 :     values[1] = LSNGetDatum(ControlFile->checkPointCopy.redo);
     105           10 :     nulls[1] = false;
     106              : 
     107           10 :     values[2] = CStringGetTextDatum(xlogfilename);
     108           10 :     nulls[2] = false;
     109              : 
     110           10 :     values[3] = Int32GetDatum(ControlFile->checkPointCopy.ThisTimeLineID);
     111           10 :     nulls[3] = false;
     112              : 
     113           10 :     values[4] = Int32GetDatum(ControlFile->checkPointCopy.PrevTimeLineID);
     114           10 :     nulls[4] = false;
     115              : 
     116           10 :     values[5] = BoolGetDatum(ControlFile->checkPointCopy.fullPageWrites);
     117           10 :     nulls[5] = false;
     118              : 
     119           10 :     values[6] = CStringGetTextDatum(psprintf("%u:%u",
     120              :                                              EpochFromFullTransactionId(ControlFile->checkPointCopy.nextXid),
     121              :                                              XidFromFullTransactionId(ControlFile->checkPointCopy.nextXid)));
     122           10 :     nulls[6] = false;
     123              : 
     124           10 :     values[7] = ObjectIdGetDatum(ControlFile->checkPointCopy.nextOid);
     125           10 :     nulls[7] = false;
     126              : 
     127           10 :     values[8] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMulti);
     128           10 :     nulls[8] = false;
     129              : 
     130           10 :     values[9] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMultiOffset);
     131           10 :     nulls[9] = false;
     132              : 
     133           10 :     values[10] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestXid);
     134           10 :     nulls[10] = false;
     135              : 
     136           10 :     values[11] = ObjectIdGetDatum(ControlFile->checkPointCopy.oldestXidDB);
     137           10 :     nulls[11] = false;
     138              : 
     139           10 :     values[12] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestActiveXid);
     140           10 :     nulls[12] = false;
     141              : 
     142           10 :     values[13] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestMulti);
     143           10 :     nulls[13] = false;
     144              : 
     145           10 :     values[14] = ObjectIdGetDatum(ControlFile->checkPointCopy.oldestMultiDB);
     146           10 :     nulls[14] = false;
     147              : 
     148           10 :     values[15] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestCommitTsXid);
     149           10 :     nulls[15] = false;
     150              : 
     151           10 :     values[16] = TransactionIdGetDatum(ControlFile->checkPointCopy.newestCommitTsXid);
     152           10 :     nulls[16] = false;
     153              : 
     154           10 :     values[17] = TimestampTzGetDatum(time_t_to_timestamptz(ControlFile->checkPointCopy.time));
     155           10 :     nulls[17] = false;
     156              : 
     157           10 :     htup = heap_form_tuple(tupdesc, values, nulls);
     158              : 
     159           10 :     PG_RETURN_DATUM(HeapTupleGetDatum(htup));
     160              : }
     161              : 
     162              : Datum
     163            4 : 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            4 :     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            4 :     LWLockAcquire(ControlFileLock, LW_SHARED);
     177            4 :     ControlFile = get_controlfile(DataDir, &crc_ok);
     178            4 :     LWLockRelease(ControlFileLock);
     179            4 :     if (!crc_ok)
     180            0 :         ereport(ERROR,
     181              :                 (errmsg("calculated CRC checksum does not match value stored in file")));
     182              : 
     183            4 :     values[0] = LSNGetDatum(ControlFile->minRecoveryPoint);
     184            4 :     nulls[0] = false;
     185              : 
     186            4 :     values[1] = Int32GetDatum(ControlFile->minRecoveryPointTLI);
     187            4 :     nulls[1] = false;
     188              : 
     189            4 :     values[2] = LSNGetDatum(ControlFile->backupStartPoint);
     190            4 :     nulls[2] = false;
     191              : 
     192            4 :     values[3] = LSNGetDatum(ControlFile->backupEndPoint);
     193            4 :     nulls[3] = false;
     194              : 
     195            4 :     values[4] = BoolGetDatum(ControlFile->backupEndRequired);
     196            4 :     nulls[4] = false;
     197              : 
     198            4 :     htup = heap_form_tuple(tupdesc, values, nulls);
     199              : 
     200            4 :     PG_RETURN_DATUM(HeapTupleGetDatum(htup));
     201              : }
     202              : 
     203              : Datum
     204            5 : 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            5 :     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            5 :     LWLockAcquire(ControlFileLock, LW_SHARED);
     218            5 :     ControlFile = get_controlfile(DataDir, &crc_ok);
     219            5 :     LWLockRelease(ControlFileLock);
     220            5 :     if (!crc_ok)
     221            0 :         ereport(ERROR,
     222              :                 (errmsg("calculated CRC checksum does not match value stored in file")));
     223              : 
     224            5 :     values[0] = Int32GetDatum(ControlFile->maxAlign);
     225            5 :     nulls[0] = false;
     226              : 
     227            5 :     values[1] = Int32GetDatum(ControlFile->blcksz);
     228            5 :     nulls[1] = false;
     229              : 
     230            5 :     values[2] = Int32GetDatum(ControlFile->relseg_size);
     231            5 :     nulls[2] = false;
     232              : 
     233            5 :     values[3] = Int32GetDatum(ControlFile->xlog_blcksz);
     234            5 :     nulls[3] = false;
     235              : 
     236            5 :     values[4] = Int32GetDatum(ControlFile->xlog_seg_size);
     237            5 :     nulls[4] = false;
     238              : 
     239            5 :     values[5] = Int32GetDatum(ControlFile->nameDataLen);
     240            5 :     nulls[5] = false;
     241              : 
     242            5 :     values[6] = Int32GetDatum(ControlFile->indexMaxKeys);
     243            5 :     nulls[6] = false;
     244              : 
     245            5 :     values[7] = Int32GetDatum(ControlFile->toast_max_chunk_size);
     246            5 :     nulls[7] = false;
     247              : 
     248            5 :     values[8] = Int32GetDatum(ControlFile->loblksize);
     249            5 :     nulls[8] = false;
     250              : 
     251            5 :     values[9] = BoolGetDatum(ControlFile->float8ByVal);
     252            5 :     nulls[9] = false;
     253              : 
     254            5 :     values[10] = Int32GetDatum(ControlFile->data_checksum_version);
     255            5 :     nulls[10] = false;
     256              : 
     257            5 :     values[11] = BoolGetDatum(ControlFile->default_char_signedness);
     258            5 :     nulls[11] = false;
     259              : 
     260            5 :     htup = heap_form_tuple(tupdesc, values, nulls);
     261              : 
     262            5 :     PG_RETURN_DATUM(HeapTupleGetDatum(htup));
     263              : }
        

Generated by: LCOV version 2.0-1