PostgreSQL Source Code git master
Loading...
Searching...
No Matches
relation_stats.c
Go to the documentation of this file.
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-2026, 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"
26#include "utils/builtins.h"
27#include "utils/fmgroids.h"
28#include "utils/fmgrprotos.h"
29#include "utils/lsyscache.h"
30#include "utils/syscache.h"
31
32
33/*
34 * Positional argument numbers, names, and types for
35 * relation_statistics_update().
36 */
37
48
49static struct StatsArgInfo relarginfo[] =
50{
51 [RELSCHEMA_ARG] = {"schemaname", TEXTOID},
52 [RELNAME_ARG] = {"relname", TEXTOID},
53 [RELPAGES_ARG] = {"relpages", INT4OID},
54 [RELTUPLES_ARG] = {"reltuples", FLOAT4OID},
55 [RELALLVISIBLE_ARG] = {"relallvisible", INT4OID},
56 [RELALLFROZEN_ARG] = {"relallfrozen", INT4OID},
58};
59
62 FunctionCallInfo fcinfo);
63
64/*
65 * Internal function for modifying statistics for a relation.
66 */
67static bool
69{
70 char *nspname;
71 char *relname;
72 Oid reloid;
74
77
80
84 errmsg("recovery is in progress"),
85 errhint("Statistics cannot be modified during recovery.")));
86
87 reloid = RangeVarGetRelidExtended(makeRangeVar(nspname, relname, -1),
90
91 return relation_statistics_update_internal(reloid, fcinfo);
92}
93
94/*
95 * Workhorse function for relation_statistics_update.
96 */
97static bool
99{
100 BlockNumber relpages = 0;
101 bool update_relpages = false;
102 float reltuples = 0;
103 bool update_reltuples = false;
104 BlockNumber relallvisible = 0;
105 bool update_relallvisible = false;
106 BlockNumber relallfrozen = 0;
107 bool update_relallfrozen = false;
111 int replaces[4] = {0};
112 Datum values[4] = {0};
113 bool nulls[4] = {0};
114 int nreplaces = 0;
115 bool result = true;
116
118 {
119 relpages = PG_GETARG_UINT32(RELPAGES_ARG);
120 update_relpages = true;
121 }
122
124 {
125 reltuples = PG_GETARG_FLOAT4(RELTUPLES_ARG);
126 if (reltuples < -1.0)
127 {
130 errmsg("argument \"%s\" must not be less than -1.0", "reltuples")));
131 result = false;
132 }
133 else
134 update_reltuples = true;
135 }
136
138 {
139 relallvisible = PG_GETARG_UINT32(RELALLVISIBLE_ARG);
141 }
142
144 {
145 relallfrozen = PG_GETARG_UINT32(RELALLFROZEN_ARG);
146 update_relallfrozen = true;
147 }
148
149 /*
150 * Take RowExclusiveLock on pg_class, consistent with
151 * vac_update_relstats().
152 */
154
157 elog(ERROR, "pg_class entry for relid %u not found", reloid);
158
160
161 if (update_relpages && relpages != pgcform->relpages)
162 {
164 values[nreplaces] = UInt32GetDatum(relpages);
165 nreplaces++;
166 }
167
168 if (update_reltuples && reltuples != pgcform->reltuples)
169 {
171 values[nreplaces] = Float4GetDatum(reltuples);
172 nreplaces++;
173 }
174
175 if (update_relallvisible && relallvisible != pgcform->relallvisible)
176 {
178 values[nreplaces] = UInt32GetDatum(relallvisible);
179 nreplaces++;
180 }
181
182 if (update_relallfrozen && relallfrozen != pgcform->relallfrozen)
183 {
185 values[nreplaces] = UInt32GetDatum(relallfrozen);
186 nreplaces++;
187 }
188
189 if (nreplaces > 0)
190 {
193
195 replaces, values, nulls);
198 }
199
201
202 /* release the lock, consistent with vac_update_relstats() */
204
206
207 return result;
208}
209
210/*
211 * Clear statistics for a given pg_class entry; that is, set back to initial
212 * stats for a newly-created table.
213 */
214Datum
216{
218
220
221 newfcinfo->args[0].value = PG_GETARG_DATUM(0);
222 newfcinfo->args[0].isnull = PG_ARGISNULL(0);
223 newfcinfo->args[1].value = PG_GETARG_DATUM(1);
224 newfcinfo->args[1].isnull = PG_ARGISNULL(1);
225 newfcinfo->args[2].value = UInt32GetDatum(0);
226 newfcinfo->args[2].isnull = false;
227 newfcinfo->args[3].value = Float4GetDatum(-1.0);
228 newfcinfo->args[3].isnull = false;
229 newfcinfo->args[4].value = UInt32GetDatum(0);
230 newfcinfo->args[4].isnull = false;
231 newfcinfo->args[5].value = UInt32GetDatum(0);
232 newfcinfo->args[5].isnull = false;
233
236}
237
238Datum
257
258/*
259 * Import relation statistics from NullableDatum inputs for all statistical
260 * values.
261 *
262 * For now, the 'version' argument is ignored. In the future it can be used
263 * to interpret older statistics properly.
264 */
265bool
267 const NullableDatum *version,
268 const NullableDatum *relpages,
269 const NullableDatum *reltuples,
270 const NullableDatum *relallvisible,
271 const NullableDatum *relallfrozen)
272{
274
275 Assert(relpages);
276 Assert(reltuples);
277 Assert(relallvisible);
278 Assert(relallfrozen);
279
282
283 newfcinfo->args[RELSCHEMA_ARG].value =
285 newfcinfo->args[RELSCHEMA_ARG].isnull = false;
286 newfcinfo->args[RELNAME_ARG].value =
288 newfcinfo->args[RELNAME_ARG].isnull = false;
289
290 newfcinfo->args[RELPAGES_ARG] = *relpages;
291 newfcinfo->args[RELTUPLES_ARG] = *reltuples;
292 newfcinfo->args[RELALLVISIBLE_ARG] = *relallvisible;
293 newfcinfo->args[RELALLFROZEN_ARG] = *relallfrozen;
294
296 newfcinfo);
297}
uint32 BlockNumber
Definition block.h:31
static Datum values[MAXATTR]
Definition bootstrap.c:190
#define CStringGetTextDatum(s)
Definition builtins.h:98
#define TextDatumGetCString(d)
Definition builtins.h:99
#define Assert(condition)
Definition c.h:1002
uint32 result
int errcode(int sqlerrcode)
Definition elog.c:875
int errhint(const char *fmt,...) pg_attribute_printf(1
#define WARNING
Definition elog.h:37
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define ereport(elevel,...)
Definition elog.h:152
#define PG_RETURN_VOID()
Definition fmgr.h:350
#define PG_GETARG_UINT32(n)
Definition fmgr.h:270
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Definition fmgr.h:150
#define PG_ARGISNULL(n)
Definition fmgr.h:209
#define PG_GETARG_DATUM(n)
Definition fmgr.h:268
#define LOCAL_FCINFO(name, nargs)
Definition fmgr.h:110
#define PG_GETARG_FLOAT4(n)
Definition fmgr.h:282
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
HeapTuple heap_modify_tuple_by_cols(HeapTuple tuple, TupleDesc tupleDesc, int nCols, const int *replCols, const Datum *replValues, const bool *replIsnull)
Definition heaptuple.c:1186
void heap_freetuple(HeapTuple htup)
Definition heaptuple.c:1372
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)
Definition indexing.c:313
#define ShareUpdateExclusiveLock
Definition lockdefs.h:39
#define RowExclusiveLock
Definition lockdefs.h:38
char * get_namespace_name(Oid nspid)
Definition lsyscache.c:3682
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition makefuncs.c:473
Oid RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
Definition namespace.c:442
static char * errmsg
NameData relname
Definition pg_class.h:40
FormData_pg_class * Form_pg_class
Definition pg_class.h:160
static Datum Float4GetDatum(float4 X)
Definition postgres.h:481
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
uint64_t Datum
Definition postgres.h:70
static Datum UInt32GetDatum(uint32 X)
Definition postgres.h:232
#define InvalidOid
unsigned int Oid
static int fb(int x)
#define RelationGetRelid(relation)
Definition rel.h:516
#define RelationGetDescr(relation)
Definition rel.h:542
#define RelationGetRelationName(relation)
Definition rel.h:550
#define RelationGetNamespace(relation)
Definition rel.h:557
static struct StatsArgInfo relarginfo[]
relation_stats_argnum
@ RELALLVISIBLE_ARG
@ RELSCHEMA_ARG
@ RELNAME_ARG
@ RELPAGES_ARG
@ RELALLFROZEN_ARG
@ RELTUPLES_ARG
@ NUM_RELATION_STATS_ARGS
Datum pg_restore_relation_stats(PG_FUNCTION_ARGS)
static bool relation_statistics_update_internal(Oid reloid, FunctionCallInfo fcinfo)
static bool relation_statistics_update(FunctionCallInfo fcinfo)
bool import_relation_statistics(Relation rel, const NullableDatum *version, const NullableDatum *relpages, const NullableDatum *reltuples, const NullableDatum *relallvisible, const NullableDatum *relallfrozen)
Datum pg_clear_relation_stats(PG_FUNCTION_ARGS)
bool stats_fill_fcinfo_from_arg_pairs(FunctionCallInfo pairs_fcinfo, FunctionCallInfo positional_fcinfo, struct StatsArgInfo *arginfo)
Definition stat_utils.c:349
void RangeVarCallbackForStats(const RangeVar *relation, Oid relId, Oid oldRelId, void *arg)
Definition stat_utils.c:143
void stats_check_required_arg(FunctionCallInfo fcinfo, struct StatsArgInfo *arginfo, int argnum)
Definition stat_utils.c:52
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:265
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:221
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40
void CommandCounterIncrement(void)
Definition xact.c:1130
bool RecoveryInProgress(void)
Definition xlog.c:6835