LCOV - differential code coverage report
Current view: top level - src/backend/statistics - relation_stats.c (source / functions) Coverage Total Hit UBC CBC
Current: a2387c32f2f8a1643c7d71b951587e6bcb2d4744 vs 371a302eecdc82274b0ae2967d18fd726a0aa6a1 Lines: 94.6 % 93 88 5 88
Current Date: 2025-10-26 12:31:50 -0700 Functions: 100.0 % 3 3 3
Baseline: lcov-20251027-010456-baseline Branches: 76.2 % 42 32 10 32
Baseline Date: 2025-10-26 11:01:32 +1300 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 100.0 % 2 2 2
(30,360] days: 95.7 % 70 67 3 67
(360..) days: 90.5 % 21 19 2 19
Function coverage date bins:
(30,360] days: 100.0 % 1 1 1
(360..) days: 100.0 % 2 2 2
Branch coverage date bins:
(30,360] days: 71.9 % 32 23 9 23
(360..) days: 90.0 % 10 9 1 9

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  * relation_stats.c
                                  3                 :                :  *
                                  4                 :                :  *    PostgreSQL relation statistics manipulation
                                  5                 :                :  *
                                  6                 :                :  * Code supporting the direct import of relation statistics, similar to
                                  7                 :                :  * what is done by the ANALYZE command.
                                  8                 :                :  *
                                  9                 :                :  * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
                                 10                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                 11                 :                :  *
                                 12                 :                :  * IDENTIFICATION
                                 13                 :                :  *       src/backend/statistics/relation_stats.c
                                 14                 :                :  *
                                 15                 :                :  *-------------------------------------------------------------------------
                                 16                 :                :  */
                                 17                 :                : 
                                 18                 :                : #include "postgres.h"
                                 19                 :                : 
                                 20                 :                : #include "access/heapam.h"
                                 21                 :                : #include "catalog/indexing.h"
                                 22                 :                : #include "catalog/namespace.h"
                                 23                 :                : #include "nodes/makefuncs.h"
                                 24                 :                : #include "statistics/stat_utils.h"
                                 25                 :                : #include "utils/builtins.h"
                                 26                 :                : #include "utils/fmgroids.h"
                                 27                 :                : #include "utils/fmgrprotos.h"
                                 28                 :                : #include "utils/lsyscache.h"
                                 29                 :                : #include "utils/syscache.h"
                                 30                 :                : 
                                 31                 :                : 
                                 32                 :                : /*
                                 33                 :                :  * Positional argument numbers, names, and types for
                                 34                 :                :  * relation_statistics_update().
                                 35                 :                :  */
                                 36                 :                : 
                                 37                 :                : enum relation_stats_argnum
                                 38                 :                : {
                                 39                 :                :     RELSCHEMA_ARG = 0,
                                 40                 :                :     RELNAME_ARG,
                                 41                 :                :     RELPAGES_ARG,
                                 42                 :                :     RELTUPLES_ARG,
                                 43                 :                :     RELALLVISIBLE_ARG,
                                 44                 :                :     RELALLFROZEN_ARG,
                                 45                 :                :     NUM_RELATION_STATS_ARGS
                                 46                 :                : };
                                 47                 :                : 
                                 48                 :                : static struct StatsArgInfo relarginfo[] =
                                 49                 :                : {
                                 50                 :                :     [RELSCHEMA_ARG] = {"schemaname", TEXTOID},
                                 51                 :                :     [RELNAME_ARG] = {"relname", TEXTOID},
                                 52                 :                :     [RELPAGES_ARG] = {"relpages", INT4OID},
                                 53                 :                :     [RELTUPLES_ARG] = {"reltuples", FLOAT4OID},
                                 54                 :                :     [RELALLVISIBLE_ARG] = {"relallvisible", INT4OID},
                                 55                 :                :     [RELALLFROZEN_ARG] = {"relallfrozen", INT4OID},
                                 56                 :                :     [NUM_RELATION_STATS_ARGS] = {0}
                                 57                 :                : };
                                 58                 :                : 
                                 59                 :                : static bool relation_statistics_update(FunctionCallInfo fcinfo);
                                 60                 :                : 
                                 61                 :                : /*
                                 62                 :                :  * Internal function for modifying statistics for a relation.
                                 63                 :                :  */
                                 64                 :                : static bool
  244 jdavis@postgresql.or       65                 :CBC        1098 : relation_statistics_update(FunctionCallInfo fcinfo)
                                 66                 :                : {
  245 tgl@sss.pgh.pa.us          67                 :           1098 :     bool        result = true;
                                 68                 :                :     char       *nspname;
                                 69                 :                :     char       *relname;
                                 70                 :                :     Oid         reloid;
                                 71                 :                :     Relation    crel;
                                 72                 :           1098 :     BlockNumber relpages = 0;
  321 jdavis@postgresql.or       73                 :           1098 :     bool        update_relpages = false;
  245 tgl@sss.pgh.pa.us          74                 :           1098 :     float       reltuples = 0;
  321 jdavis@postgresql.or       75                 :           1098 :     bool        update_reltuples = false;
  245 tgl@sss.pgh.pa.us          76                 :           1098 :     BlockNumber relallvisible = 0;
  321 jdavis@postgresql.or       77                 :           1098 :     bool        update_relallvisible = false;
  238 melanieplageman@gmai       78                 :           1098 :     BlockNumber relallfrozen = 0;
                                 79                 :           1098 :     bool        update_relallfrozen = false;
                                 80                 :                :     HeapTuple   ctup;
                                 81                 :                :     Form_pg_class pgcform;
                                 82                 :           1098 :     int         replaces[4] = {0};
                                 83                 :           1098 :     Datum       values[4] = {0};
                                 84                 :           1098 :     bool        nulls[4] = {0};
  245 jdavis@postgresql.or       85                 :           1098 :     int         nreplaces = 0;
   12 nathan@postgresql.or       86                 :           1098 :     Oid         locked_table = InvalidOid;
                                 87                 :                : 
  216 jdavis@postgresql.or       88                 :           1098 :     stats_check_required_arg(fcinfo, relarginfo, RELSCHEMA_ARG);
                                 89                 :           1092 :     stats_check_required_arg(fcinfo, relarginfo, RELNAME_ARG);
                                 90                 :                : 
                                 91                 :           1086 :     nspname = TextDatumGetCString(PG_GETARG_DATUM(RELSCHEMA_ARG));
                                 92                 :           1086 :     relname = TextDatumGetCString(PG_GETARG_DATUM(RELNAME_ARG));
                                 93                 :                : 
                                 94         [ -  + ]:           1086 :     if (RecoveryInProgress())
  216 jdavis@postgresql.or       95         [ #  # ]:UBC           0 :         ereport(ERROR,
                                 96                 :                :                 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
                                 97                 :                :                  errmsg("recovery is in progress"),
                                 98                 :                :                  errhint("Statistics cannot be modified during recovery.")));
                                 99                 :                : 
   12 nathan@postgresql.or      100                 :CBC        1086 :     reloid = RangeVarGetRelidExtended(makeRangeVar(nspname, relname, -1),
                                101                 :                :                                       ShareUpdateExclusiveLock, 0,
                                102                 :                :                                       RangeVarCallbackForStats, &locked_table);
                                103                 :                : 
  381 jdavis@postgresql.or      104         [ +  + ]:           1074 :     if (!PG_ARGISNULL(RELPAGES_ARG))
                                105                 :                :     {
  245 tgl@sss.pgh.pa.us         106                 :           1062 :         relpages = PG_GETARG_UINT32(RELPAGES_ARG);
                                107                 :           1062 :         update_relpages = true;
                                108                 :                :     }
                                109                 :                : 
  381 jdavis@postgresql.or      110         [ +  + ]:           1074 :     if (!PG_ARGISNULL(RELTUPLES_ARG))
                                111                 :                :     {
  321                           112                 :           1056 :         reltuples = PG_GETARG_FLOAT4(RELTUPLES_ARG);
  381                           113         [ -  + ]:           1056 :         if (reltuples < -1.0)
                                114                 :                :         {
  244 jdavis@postgresql.or      115         [ #  # ]:UBC           0 :             ereport(WARNING,
                                116                 :                :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                117                 :                :                      errmsg("argument \"%s\" must not be less than -1.0", "reltuples")));
  368                           118                 :              0 :             result = false;
                                119                 :                :         }
                                120                 :                :         else
  321 jdavis@postgresql.or      121                 :CBC        1056 :             update_reltuples = true;
                                122                 :                :     }
                                123                 :                : 
  381                           124         [ +  + ]:           1074 :     if (!PG_ARGISNULL(RELALLVISIBLE_ARG))
                                125                 :                :     {
  245 tgl@sss.pgh.pa.us         126                 :           1056 :         relallvisible = PG_GETARG_UINT32(RELALLVISIBLE_ARG);
                                127                 :           1056 :         update_relallvisible = true;
                                128                 :                :     }
                                129                 :                : 
  238 melanieplageman@gmai      130         [ +  + ]:           1074 :     if (!PG_ARGISNULL(RELALLFROZEN_ARG))
                                131                 :                :     {
                                132                 :           1056 :         relallfrozen = PG_GETARG_UINT32(RELALLFROZEN_ARG);
                                133                 :           1056 :         update_relallfrozen = true;
                                134                 :                :     }
                                135                 :                : 
                                136                 :                :     /*
                                137                 :                :      * Take RowExclusiveLock on pg_class, consistent with
                                138                 :                :      * vac_update_relstats().
                                139                 :                :      */
  321 jdavis@postgresql.or      140                 :           1074 :     crel = table_open(RelationRelationId, RowExclusiveLock);
                                141                 :                : 
  245                           142                 :           1074 :     ctup = SearchSysCache1(RELOID, ObjectIdGetDatum(reloid));
                                143         [ -  + ]:           1074 :     if (!HeapTupleIsValid(ctup))
  236 jdavis@postgresql.or      144         [ #  # ]:UBC           0 :         elog(ERROR, "pg_class entry for relid %u not found", reloid);
                                145                 :                : 
  245 jdavis@postgresql.or      146                 :CBC        1074 :     pgcform = (Form_pg_class) GETSTRUCT(ctup);
                                147                 :                : 
                                148   [ +  +  +  + ]:           1074 :     if (update_relpages && relpages != pgcform->relpages)
                                149                 :                :     {
                                150                 :            550 :         replaces[nreplaces] = Anum_pg_class_relpages;
                                151                 :            550 :         values[nreplaces] = UInt32GetDatum(relpages);
                                152                 :            550 :         nreplaces++;
                                153                 :                :     }
                                154                 :                : 
                                155   [ +  +  +  + ]:           1074 :     if (update_reltuples && reltuples != pgcform->reltuples)
                                156                 :                :     {
                                157                 :            492 :         replaces[nreplaces] = Anum_pg_class_reltuples;
                                158                 :            492 :         values[nreplaces] = Float4GetDatum(reltuples);
                                159                 :            492 :         nreplaces++;
                                160                 :                :     }
                                161                 :                : 
                                162   [ +  +  +  + ]:           1074 :     if (update_relallvisible && relallvisible != pgcform->relallvisible)
                                163                 :                :     {
                                164                 :            143 :         replaces[nreplaces] = Anum_pg_class_relallvisible;
                                165                 :            143 :         values[nreplaces] = UInt32GetDatum(relallvisible);
                                166                 :            143 :         nreplaces++;
                                167                 :                :     }
                                168                 :                : 
  238 melanieplageman@gmai      169   [ +  +  +  + ]:           1074 :     if (update_relallfrozen && relallfrozen != pgcform->relallfrozen)
                                170                 :                :     {
                                171                 :             40 :         replaces[nreplaces] = Anum_pg_class_relallfrozen;
                                172                 :             40 :         values[nreplaces] = UInt32GetDatum(relallfrozen);
                                173                 :             40 :         nreplaces++;
                                174                 :                :     }
                                175                 :                : 
  245 jdavis@postgresql.or      176         [ +  + ]:           1074 :     if (nreplaces > 0)
                                177                 :                :     {
                                178                 :            634 :         TupleDesc   tupdesc = RelationGetDescr(crel);
                                179                 :                :         HeapTuple   newtup;
                                180                 :                : 
                                181                 :            634 :         newtup = heap_modify_tuple_by_cols(ctup, tupdesc, nreplaces,
                                182                 :                :                                            replaces, values, nulls);
                                183                 :            634 :         CatalogTupleUpdate(crel, &newtup->t_self, newtup);
                                184                 :            634 :         heap_freetuple(newtup);
                                185                 :                :     }
                                186                 :                : 
                                187                 :           1074 :     ReleaseSysCache(ctup);
                                188                 :                : 
                                189                 :                :     /* release the lock, consistent with vac_update_relstats() */
  381                           190                 :           1074 :     table_close(crel, RowExclusiveLock);
                                191                 :                : 
  363                           192                 :           1074 :     CommandCounterIncrement();
                                193                 :                : 
  368                           194                 :           1074 :     return result;
                                195                 :                : }
                                196                 :                : 
                                197                 :                : /*
                                198                 :                :  * Clear statistics for a given pg_class entry; that is, set back to initial
                                199                 :                :  * stats for a newly-created table.
                                200                 :                :  */
                                201                 :                : Datum
  381                           202                 :             12 : pg_clear_relation_stats(PG_FUNCTION_ARGS)
                                203                 :                : {
  216                           204                 :             12 :     LOCAL_FCINFO(newfcinfo, 6);
                                205                 :                : 
                                206                 :             12 :     InitFunctionCallInfoData(*newfcinfo, NULL, 6, InvalidOid, NULL, NULL);
                                207                 :                : 
                                208                 :             12 :     newfcinfo->args[0].value = PG_GETARG_DATUM(0);
  381                           209                 :             12 :     newfcinfo->args[0].isnull = PG_ARGISNULL(0);
  216                           210                 :             12 :     newfcinfo->args[1].value = PG_GETARG_DATUM(1);
                                211                 :             12 :     newfcinfo->args[1].isnull = PG_ARGISNULL(1);
                                212                 :             12 :     newfcinfo->args[2].value = UInt32GetDatum(0);
  381                           213                 :             12 :     newfcinfo->args[2].isnull = false;
  216                           214                 :             12 :     newfcinfo->args[3].value = Float4GetDatum(-1.0);
  381                           215                 :             12 :     newfcinfo->args[3].isnull = false;
  238 melanieplageman@gmai      216                 :             12 :     newfcinfo->args[4].value = UInt32GetDatum(0);
                                217                 :             12 :     newfcinfo->args[4].isnull = false;
  216 jdavis@postgresql.or      218                 :             12 :     newfcinfo->args[5].value = UInt32GetDatum(0);
                                219                 :             12 :     newfcinfo->args[5].isnull = false;
                                220                 :                : 
  244                           221                 :             12 :     relation_statistics_update(newfcinfo);
  370                           222                 :              6 :     PG_RETURN_VOID();
                                223                 :                : }
                                224                 :                : 
                                225                 :                : Datum
  368                           226                 :           1092 : pg_restore_relation_stats(PG_FUNCTION_ARGS)
                                227                 :                : {
                                228                 :           1092 :     LOCAL_FCINFO(positional_fcinfo, NUM_RELATION_STATS_ARGS);
                                229                 :           1092 :     bool        result = true;
                                230                 :                : 
                                231                 :           1092 :     InitFunctionCallInfoData(*positional_fcinfo, NULL,
                                232                 :                :                              NUM_RELATION_STATS_ARGS,
                                233                 :                :                              InvalidOid, NULL, NULL);
                                234                 :                : 
                                235         [ +  + ]:           1092 :     if (!stats_fill_fcinfo_from_arg_pairs(fcinfo, positional_fcinfo,
                                236                 :                :                                           relarginfo))
                                237                 :             12 :         result = false;
                                238                 :                : 
  244                           239         [ -  + ]:           1086 :     if (!relation_statistics_update(positional_fcinfo))
  368 jdavis@postgresql.or      240                 :UBC           0 :         result = false;
                                241                 :                : 
  368 jdavis@postgresql.or      242                 :CBC        1068 :     PG_RETURN_BOOL(result);
                                243                 :                : }
        

Generated by: LCOV version 2.4-beta