From 1c4efffcb2e8b78da84d5c3fa47d11f3a68dd2a0 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 11 Aug 2026 15:48:27 +0200 Subject: [PATCH 1/2] Fix signed/unsigned integer handling in pg_restore_relation_stats() The pg_class fields relpages, relallvisible, and relallfrozen are of type int32, but the statistics restoration code internally dealt with them as uint32 for a little bit, after which they would turn back into int32. This doesn't make sense, so fix it to use int32 consistently throughout. --- contrib/postgres_fdw/postgres_fdw.c | 23 +---------------------- src/backend/statistics/relation_stats.c | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 33 deletions(-) diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index 479a40719bd..fb20bd7969b 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -597,7 +597,6 @@ static bool import_fetched_statistics(Relation relation, static char *get_opt_value(PGresult *res, int row, int col); static void set_text_arg(NullableDatum *arg, const char *s); static void set_int32_arg(NullableDatum *arg, const char *s); -static void set_uint32_arg(NullableDatum *arg, const char *s); static void set_float_arg(NullableDatum *arg, const char *s); static void set_floatarr_arg(NullableDatum *arg, const char *s); static void produce_tuple_asynchronously(AsyncRequest *areq, bool fetch); @@ -6105,7 +6104,7 @@ import_fetched_statistics(Relation relation, Assert(PQntuples(res) == 1); /* Set the remaining parameters. */ - set_uint32_arg(&args[1], get_opt_value(res, 0, RELSTATS_RELPAGES)); + set_int32_arg(&args[1], get_opt_value(res, 0, RELSTATS_RELPAGES)); Assert(!args[1].isnull); set_float_arg(&args[2], get_opt_value(res, 0, RELSTATS_RELTUPLES)); Assert(!args[2].isnull); @@ -6176,26 +6175,6 @@ set_int32_arg(NullableDatum *arg, const char *s) } } -/* - * Convenience routine for setting optional uint32 arguments - */ -static void -set_uint32_arg(NullableDatum *arg, const char *s) -{ - if (s) - { - uint32 val = uint32in_subr(s, NULL, "uint32", NULL); - - arg->value = UInt32GetDatum(val); - arg->isnull = false; - } - else - { - arg->value = (Datum) 0; - arg->isnull = true; - } -} - /* * Convenience routine for setting optional float arguments */ diff --git a/src/backend/statistics/relation_stats.c b/src/backend/statistics/relation_stats.c index 9de5d64c384..d9bc77e369c 100644 --- a/src/backend/statistics/relation_stats.c +++ b/src/backend/statistics/relation_stats.c @@ -99,13 +99,13 @@ relation_statistics_update(FunctionCallInfo fcinfo) static bool relation_statistics_update_internal(Oid reloid, FunctionCallInfo fcinfo) { - BlockNumber relpages = 0; + int32 relpages = 0; bool update_relpages = false; float reltuples = 0; bool update_reltuples = false; - BlockNumber relallvisible = 0; + int32 relallvisible = 0; bool update_relallvisible = false; - BlockNumber relallfrozen = 0; + int32 relallfrozen = 0; bool update_relallfrozen = false; Relation crel; HeapTuple ctup; @@ -145,13 +145,13 @@ relation_statistics_update_internal(Oid reloid, FunctionCallInfo fcinfo) if (!PG_ARGISNULL(RELALLVISIBLE_ARG)) { - relallvisible = PG_GETARG_UINT32(RELALLVISIBLE_ARG); + relallvisible = PG_GETARG_INT32(RELALLVISIBLE_ARG); update_relallvisible = true; } if (!PG_ARGISNULL(RELALLFROZEN_ARG)) { - relallfrozen = PG_GETARG_UINT32(RELALLFROZEN_ARG); + relallfrozen = PG_GETARG_INT32(RELALLFROZEN_ARG); update_relallfrozen = true; } @@ -170,7 +170,7 @@ relation_statistics_update_internal(Oid reloid, FunctionCallInfo fcinfo) if (update_relpages && relpages != pgcform->relpages) { replaces[nreplaces] = Anum_pg_class_relpages; - values[nreplaces] = UInt32GetDatum(relpages); + values[nreplaces] = Int32GetDatum(relpages); nreplaces++; } @@ -184,14 +184,14 @@ relation_statistics_update_internal(Oid reloid, FunctionCallInfo fcinfo) if (update_relallvisible && relallvisible != pgcform->relallvisible) { replaces[nreplaces] = Anum_pg_class_relallvisible; - values[nreplaces] = UInt32GetDatum(relallvisible); + values[nreplaces] = Int32GetDatum(relallvisible); nreplaces++; } if (update_relallfrozen && relallfrozen != pgcform->relallfrozen) { replaces[nreplaces] = Anum_pg_class_relallfrozen; - values[nreplaces] = UInt32GetDatum(relallfrozen); + values[nreplaces] = Int32GetDatum(relallfrozen); nreplaces++; } @@ -231,13 +231,13 @@ pg_clear_relation_stats(PG_FUNCTION_ARGS) newfcinfo->args[0].isnull = PG_ARGISNULL(0); newfcinfo->args[1].value = PG_GETARG_DATUM(1); newfcinfo->args[1].isnull = PG_ARGISNULL(1); - newfcinfo->args[2].value = UInt32GetDatum(0); + newfcinfo->args[2].value = Int32GetDatum(0); newfcinfo->args[2].isnull = false; newfcinfo->args[3].value = Float4GetDatum(-1.0); newfcinfo->args[3].isnull = false; - newfcinfo->args[4].value = UInt32GetDatum(0); + newfcinfo->args[4].value = Int32GetDatum(0); newfcinfo->args[4].isnull = false; - newfcinfo->args[5].value = UInt32GetDatum(0); + newfcinfo->args[5].value = Int32GetDatum(0); newfcinfo->args[5].isnull = false; relation_statistics_update(newfcinfo); -- 2.55.0