LCOV - differential code coverage report
Current view: top level - src/backend/statistics - relation_stats.c (source / functions) Coverage Total Hit UBC CBC
Current: c70b6db34ffeab48beef1fb4ce61bcad3772b8dd vs 06473f5a344df8c9594ead90a609b86f6724cff8 Lines: 94.6 % 93 88 5 88
Current Date: 2025-09-06 07:49:51 +0900 Functions: 100.0 % 3 3 3
Baseline: lcov-20250906-005545-baseline Branches: 76.2 % 42 32 10 32
Baseline Date: 2025-09-05 08:21:35 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(30,360] days: 94.6 % 93 88 5 88
Function coverage date bins:
(30,360] days: 100.0 % 3 3 3
Branch coverage date bins:
(30,360] days: 76.2 % 42 32 10 32

 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 "statistics/stat_utils.h"
                                 24                 :                : #include "utils/builtins.h"
                                 25                 :                : #include "utils/fmgroids.h"
                                 26                 :                : #include "utils/fmgrprotos.h"
                                 27                 :                : #include "utils/lsyscache.h"
                                 28                 :                : #include "utils/syscache.h"
                                 29                 :                : 
                                 30                 :                : 
                                 31                 :                : /*
                                 32                 :                :  * Positional argument numbers, names, and types for
                                 33                 :                :  * relation_statistics_update().
                                 34                 :                :  */
                                 35                 :                : 
                                 36                 :                : enum relation_stats_argnum
                                 37                 :                : {
                                 38                 :                :     RELSCHEMA_ARG = 0,
                                 39                 :                :     RELNAME_ARG,
                                 40                 :                :     RELPAGES_ARG,
                                 41                 :                :     RELTUPLES_ARG,
                                 42                 :                :     RELALLVISIBLE_ARG,
                                 43                 :                :     RELALLFROZEN_ARG,
                                 44                 :                :     NUM_RELATION_STATS_ARGS
                                 45                 :                : };
                                 46                 :                : 
                                 47                 :                : static struct StatsArgInfo relarginfo[] =
                                 48                 :                : {
                                 49                 :                :     [RELSCHEMA_ARG] = {"schemaname", TEXTOID},
                                 50                 :                :     [RELNAME_ARG] = {"relname", TEXTOID},
                                 51                 :                :     [RELPAGES_ARG] = {"relpages", INT4OID},
                                 52                 :                :     [RELTUPLES_ARG] = {"reltuples", FLOAT4OID},
                                 53                 :                :     [RELALLVISIBLE_ARG] = {"relallvisible", INT4OID},
                                 54                 :                :     [RELALLFROZEN_ARG] = {"relallfrozen", INT4OID},
                                 55                 :                :     [NUM_RELATION_STATS_ARGS] = {0}
                                 56                 :                : };
                                 57                 :                : 
                                 58                 :                : static bool relation_statistics_update(FunctionCallInfo fcinfo);
                                 59                 :                : 
                                 60                 :                : /*
                                 61                 :                :  * Internal function for modifying statistics for a relation.
                                 62                 :                :  */
                                 63                 :                : static bool
  193 jdavis@postgresql.or       64                 :CBC        1097 : relation_statistics_update(FunctionCallInfo fcinfo)
                                 65                 :                : {
  194 tgl@sss.pgh.pa.us          66                 :           1097 :     bool        result = true;
                                 67                 :                :     char       *nspname;
                                 68                 :                :     char       *relname;
                                 69                 :                :     Oid         reloid;
                                 70                 :                :     Relation    crel;
                                 71                 :           1097 :     BlockNumber relpages = 0;
  270 jdavis@postgresql.or       72                 :           1097 :     bool        update_relpages = false;
  194 tgl@sss.pgh.pa.us          73                 :           1097 :     float       reltuples = 0;
  270 jdavis@postgresql.or       74                 :           1097 :     bool        update_reltuples = false;
  194 tgl@sss.pgh.pa.us          75                 :           1097 :     BlockNumber relallvisible = 0;
  270 jdavis@postgresql.or       76                 :           1097 :     bool        update_relallvisible = false;
  187 melanieplageman@gmai       77                 :           1097 :     BlockNumber relallfrozen = 0;
                                 78                 :           1097 :     bool        update_relallfrozen = false;
                                 79                 :                :     HeapTuple   ctup;
                                 80                 :                :     Form_pg_class pgcform;
                                 81                 :           1097 :     int         replaces[4] = {0};
                                 82                 :           1097 :     Datum       values[4] = {0};
                                 83                 :           1097 :     bool        nulls[4] = {0};
  194 jdavis@postgresql.or       84                 :           1097 :     int         nreplaces = 0;
                                 85                 :                : 
  165                            86                 :           1097 :     stats_check_required_arg(fcinfo, relarginfo, RELSCHEMA_ARG);
                                 87                 :           1091 :     stats_check_required_arg(fcinfo, relarginfo, RELNAME_ARG);
                                 88                 :                : 
                                 89                 :           1085 :     nspname = TextDatumGetCString(PG_GETARG_DATUM(RELSCHEMA_ARG));
                                 90                 :           1085 :     relname = TextDatumGetCString(PG_GETARG_DATUM(RELNAME_ARG));
                                 91                 :                : 
                                 92                 :           1085 :     reloid = stats_lookup_relid(nspname, relname);
                                 93                 :                : 
                                 94         [ -  + ]:           1082 :     if (RecoveryInProgress())
  165 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                 :                : 
  165 jdavis@postgresql.or      100                 :CBC        1082 :     stats_lock_check_privileges(reloid);
                                101                 :                : 
  330                           102         [ +  + ]:           1073 :     if (!PG_ARGISNULL(RELPAGES_ARG))
                                103                 :                :     {
  194 tgl@sss.pgh.pa.us         104                 :           1061 :         relpages = PG_GETARG_UINT32(RELPAGES_ARG);
                                105                 :           1061 :         update_relpages = true;
                                106                 :                :     }
                                107                 :                : 
  330 jdavis@postgresql.or      108         [ +  + ]:           1073 :     if (!PG_ARGISNULL(RELTUPLES_ARG))
                                109                 :                :     {
  270                           110                 :           1055 :         reltuples = PG_GETARG_FLOAT4(RELTUPLES_ARG);
  330                           111         [ -  + ]:           1055 :         if (reltuples < -1.0)
                                112                 :                :         {
  193 jdavis@postgresql.or      113         [ #  # ]:UBC           0 :             ereport(WARNING,
                                114                 :                :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                115                 :                :                      errmsg("argument \"%s\" must not be less than -1.0", "reltuples")));
  317                           116                 :              0 :             result = false;
                                117                 :                :         }
                                118                 :                :         else
  270 jdavis@postgresql.or      119                 :CBC        1055 :             update_reltuples = true;
                                120                 :                :     }
                                121                 :                : 
  330                           122         [ +  + ]:           1073 :     if (!PG_ARGISNULL(RELALLVISIBLE_ARG))
                                123                 :                :     {
  194 tgl@sss.pgh.pa.us         124                 :           1055 :         relallvisible = PG_GETARG_UINT32(RELALLVISIBLE_ARG);
                                125                 :           1055 :         update_relallvisible = true;
                                126                 :                :     }
                                127                 :                : 
  187 melanieplageman@gmai      128         [ +  + ]:           1073 :     if (!PG_ARGISNULL(RELALLFROZEN_ARG))
                                129                 :                :     {
                                130                 :           1055 :         relallfrozen = PG_GETARG_UINT32(RELALLFROZEN_ARG);
                                131                 :           1055 :         update_relallfrozen = true;
                                132                 :                :     }
                                133                 :                : 
                                134                 :                :     /*
                                135                 :                :      * Take RowExclusiveLock on pg_class, consistent with
                                136                 :                :      * vac_update_relstats().
                                137                 :                :      */
  270 jdavis@postgresql.or      138                 :           1073 :     crel = table_open(RelationRelationId, RowExclusiveLock);
                                139                 :                : 
  194                           140                 :           1073 :     ctup = SearchSysCache1(RELOID, ObjectIdGetDatum(reloid));
                                141         [ -  + ]:           1073 :     if (!HeapTupleIsValid(ctup))
  185 jdavis@postgresql.or      142         [ #  # ]:UBC           0 :         elog(ERROR, "pg_class entry for relid %u not found", reloid);
                                143                 :                : 
  194 jdavis@postgresql.or      144                 :CBC        1073 :     pgcform = (Form_pg_class) GETSTRUCT(ctup);
                                145                 :                : 
                                146   [ +  +  +  + ]:           1073 :     if (update_relpages && relpages != pgcform->relpages)
                                147                 :                :     {
                                148                 :            550 :         replaces[nreplaces] = Anum_pg_class_relpages;
                                149                 :            550 :         values[nreplaces] = UInt32GetDatum(relpages);
                                150                 :            550 :         nreplaces++;
                                151                 :                :     }
                                152                 :                : 
                                153   [ +  +  +  + ]:           1073 :     if (update_reltuples && reltuples != pgcform->reltuples)
                                154                 :                :     {
                                155                 :            490 :         replaces[nreplaces] = Anum_pg_class_reltuples;
                                156                 :            490 :         values[nreplaces] = Float4GetDatum(reltuples);
                                157                 :            490 :         nreplaces++;
                                158                 :                :     }
                                159                 :                : 
                                160   [ +  +  +  + ]:           1073 :     if (update_relallvisible && relallvisible != pgcform->relallvisible)
                                161                 :                :     {
                                162                 :            143 :         replaces[nreplaces] = Anum_pg_class_relallvisible;
                                163                 :            143 :         values[nreplaces] = UInt32GetDatum(relallvisible);
                                164                 :            143 :         nreplaces++;
                                165                 :                :     }
                                166                 :                : 
  187 melanieplageman@gmai      167   [ +  +  +  + ]:           1073 :     if (update_relallfrozen && relallfrozen != pgcform->relallfrozen)
                                168                 :                :     {
                                169                 :             40 :         replaces[nreplaces] = Anum_pg_class_relallfrozen;
                                170                 :             40 :         values[nreplaces] = UInt32GetDatum(relallfrozen);
                                171                 :             40 :         nreplaces++;
                                172                 :                :     }
                                173                 :                : 
  194 jdavis@postgresql.or      174         [ +  + ]:           1073 :     if (nreplaces > 0)
                                175                 :                :     {
                                176                 :            632 :         TupleDesc   tupdesc = RelationGetDescr(crel);
                                177                 :                :         HeapTuple   newtup;
                                178                 :                : 
                                179                 :            632 :         newtup = heap_modify_tuple_by_cols(ctup, tupdesc, nreplaces,
                                180                 :                :                                            replaces, values, nulls);
                                181                 :            632 :         CatalogTupleUpdate(crel, &newtup->t_self, newtup);
                                182                 :            632 :         heap_freetuple(newtup);
                                183                 :                :     }
                                184                 :                : 
                                185                 :           1073 :     ReleaseSysCache(ctup);
                                186                 :                : 
                                187                 :                :     /* release the lock, consistent with vac_update_relstats() */
  330                           188                 :           1073 :     table_close(crel, RowExclusiveLock);
                                189                 :                : 
  312                           190                 :           1073 :     CommandCounterIncrement();
                                191                 :                : 
  317                           192                 :           1073 :     return result;
                                193                 :                : }
                                194                 :                : 
                                195                 :                : /*
                                196                 :                :  * Clear statistics for a given pg_class entry; that is, set back to initial
                                197                 :                :  * stats for a newly-created table.
                                198                 :                :  */
                                199                 :                : Datum
  330                           200                 :             12 : pg_clear_relation_stats(PG_FUNCTION_ARGS)
                                201                 :                : {
  165                           202                 :             12 :     LOCAL_FCINFO(newfcinfo, 6);
                                203                 :                : 
                                204                 :             12 :     InitFunctionCallInfoData(*newfcinfo, NULL, 6, InvalidOid, NULL, NULL);
                                205                 :                : 
                                206                 :             12 :     newfcinfo->args[0].value = PG_GETARG_DATUM(0);
  330                           207                 :             12 :     newfcinfo->args[0].isnull = PG_ARGISNULL(0);
  165                           208                 :             12 :     newfcinfo->args[1].value = PG_GETARG_DATUM(1);
                                209                 :             12 :     newfcinfo->args[1].isnull = PG_ARGISNULL(1);
                                210                 :             12 :     newfcinfo->args[2].value = UInt32GetDatum(0);
  330                           211                 :             12 :     newfcinfo->args[2].isnull = false;
  165                           212                 :             12 :     newfcinfo->args[3].value = Float4GetDatum(-1.0);
  330                           213                 :             12 :     newfcinfo->args[3].isnull = false;
  187 melanieplageman@gmai      214                 :             12 :     newfcinfo->args[4].value = UInt32GetDatum(0);
                                215                 :             12 :     newfcinfo->args[4].isnull = false;
  165 jdavis@postgresql.or      216                 :             12 :     newfcinfo->args[5].value = UInt32GetDatum(0);
                                217                 :             12 :     newfcinfo->args[5].isnull = false;
                                218                 :                : 
  193                           219                 :             12 :     relation_statistics_update(newfcinfo);
  319                           220                 :              6 :     PG_RETURN_VOID();
                                221                 :                : }
                                222                 :                : 
                                223                 :                : Datum
  317                           224                 :           1091 : pg_restore_relation_stats(PG_FUNCTION_ARGS)
                                225                 :                : {
                                226                 :           1091 :     LOCAL_FCINFO(positional_fcinfo, NUM_RELATION_STATS_ARGS);
                                227                 :           1091 :     bool        result = true;
                                228                 :                : 
                                229                 :           1091 :     InitFunctionCallInfoData(*positional_fcinfo, NULL,
                                230                 :                :                              NUM_RELATION_STATS_ARGS,
                                231                 :                :                              InvalidOid, NULL, NULL);
                                232                 :                : 
                                233         [ +  + ]:           1091 :     if (!stats_fill_fcinfo_from_arg_pairs(fcinfo, positional_fcinfo,
                                234                 :                :                                           relarginfo))
                                235                 :             12 :         result = false;
                                236                 :                : 
  193                           237         [ -  + ]:           1085 :     if (!relation_statistics_update(positional_fcinfo))
  317 jdavis@postgresql.or      238                 :UBC           0 :         result = false;
                                239                 :                : 
  317 jdavis@postgresql.or      240                 :CBC        1067 :     PG_RETURN_BOOL(result);
                                241                 :                : }
        

Generated by: LCOV version 2.4-beta