1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-22 23:02:54 +03:00

Fix confusion about data type of pg_class.relpages and relallvisible.

Although they're exposed as int4 in pg_class, relpages and
relallvisible are really of type BlockNumber, that is uint32.
Correct type puns in relation_statistics_update() and remove
inappropriate range-checks.  The type puns are only cosmetic
issues, but the range checks would cause failures with huge
relations.

Reported-by: Tom Lane <tgl@sss.pgh.pa.us>
Author: Corey Huinker <corey.huinker@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/614341.1740269035@sss.pgh.pa.us
This commit is contained in:
Tom Lane 2025-02-24 11:16:04 -05:00
parent e889422d98
commit 9de2cc455e

View File

@ -24,9 +24,6 @@
#include "utils/fmgrprotos.h"
#include "utils/syscache.h"
#define DEFAULT_RELPAGES Int32GetDatum(0)
#define DEFAULT_RELTUPLES Float4GetDatum(-1.0)
#define DEFAULT_RELALLVISIBLE Int32GetDatum(0)
/*
* Positional argument numbers, names, and types for
@ -60,40 +57,25 @@ static bool relation_statistics_update(FunctionCallInfo fcinfo, int elevel,
static bool
relation_statistics_update(FunctionCallInfo fcinfo, int elevel, bool inplace)
{
bool result = true;
Oid reloid;
Relation crel;
int32 relpages = DEFAULT_RELPAGES;
BlockNumber relpages = 0;
bool update_relpages = false;
float reltuples = DEFAULT_RELTUPLES;
float reltuples = 0;
bool update_reltuples = false;
int32 relallvisible = DEFAULT_RELALLVISIBLE;
BlockNumber relallvisible = 0;
bool update_relallvisible = false;
bool result = true;
if (!PG_ARGISNULL(RELPAGES_ARG))
{
relpages = PG_GETARG_INT32(RELPAGES_ARG);
/*
* Partitioned tables may have relpages=-1. Note: for relations with
* no storage, relpages=-1 is not used consistently, but must be
* supported here.
*/
if (relpages < -1)
{
ereport(elevel,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("relpages cannot be < -1")));
result = false;
}
else
relpages = PG_GETARG_UINT32(RELPAGES_ARG);
update_relpages = true;
}
if (!PG_ARGISNULL(RELTUPLES_ARG))
{
reltuples = PG_GETARG_FLOAT4(RELTUPLES_ARG);
if (reltuples < -1.0)
{
ereport(elevel,
@ -107,16 +89,7 @@ relation_statistics_update(FunctionCallInfo fcinfo, int elevel, bool inplace)
if (!PG_ARGISNULL(RELALLVISIBLE_ARG))
{
relallvisible = PG_GETARG_INT32(RELALLVISIBLE_ARG);
if (relallvisible < 0)
{
ereport(elevel,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("relallvisible cannot be < 0")));
result = false;
}
else
relallvisible = PG_GETARG_UINT32(RELALLVISIBLE_ARG);
update_relallvisible = true;
}
@ -201,7 +174,7 @@ relation_statistics_update(FunctionCallInfo fcinfo, int elevel, bool inplace)
if (update_relpages && relpages != pgcform->relpages)
{
replaces[nreplaces] = Anum_pg_class_relpages;
values[nreplaces] = Int32GetDatum(relpages);
values[nreplaces] = UInt32GetDatum(relpages);
nreplaces++;
}
@ -215,7 +188,7 @@ relation_statistics_update(FunctionCallInfo fcinfo, int elevel, bool inplace)
if (update_relallvisible && relallvisible != pgcform->relallvisible)
{
replaces[nreplaces] = Anum_pg_class_relallvisible;
values[nreplaces] = Int32GetDatum(relallvisible);
values[nreplaces] = UInt32GetDatum(relallvisible);
nreplaces++;
}
@ -263,11 +236,11 @@ pg_clear_relation_stats(PG_FUNCTION_ARGS)
newfcinfo->args[0].value = PG_GETARG_OID(0);
newfcinfo->args[0].isnull = PG_ARGISNULL(0);
newfcinfo->args[1].value = DEFAULT_RELPAGES;
newfcinfo->args[1].value = UInt32GetDatum(0);
newfcinfo->args[1].isnull = false;
newfcinfo->args[2].value = DEFAULT_RELTUPLES;
newfcinfo->args[2].value = Float4GetDatum(-1.0);
newfcinfo->args[2].isnull = false;
newfcinfo->args[3].value = DEFAULT_RELALLVISIBLE;
newfcinfo->args[3].value = UInt32GetDatum(0);
newfcinfo->args[3].isnull = false;
relation_statistics_update(newfcinfo, ERROR, false);