From d0cf1bd1dc5e812330c633fb2f13f039463179a3 Mon Sep 17 00:00:00 2001 From: Atish Prakash <125atishprak@gmail.com> Date: Sun, 8 Nov 2026 23:44:42 -0500 Subject: [PATCH REL_19 v3 1/2] Store empty stavalues for expression statistics, as ANALYZE does Since 261f89a976b a slot can have no values. update_attstats() stores an empty array then, but serialize_expr_stats() still stored a NULL, which the planner rejects. The two functions build pg_statistic tuples the same way. Add comments to both saying they must be kept in sync. Co-authored-by: Shihao Zhong Discussion: https://postgr.es/m/19849-38b8bd2fea807154@postgresql.org --- src/backend/commands/analyze.c | 5 ++++- src/backend/statistics/extended_stats.c | 14 +++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index e7f664e4f89..cd5c95d957e 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -1766,7 +1766,10 @@ update_attstats(Oid relid, bool inh, int natts, VacAttrStats **vacattrstats) continue; /* - * Construct a new pg_statistic tuple + * Construct a new pg_statistic tuple. + * + * serialize_expr_stats() in extended_stats.c builds pg_statistic + * tuples the same way, so keep the two in sync. */ for (i = 0; i < Natts_pg_statistic; ++i) { diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c index 1f9a25a3af0..f12d49bda4c 100644 --- a/src/backend/statistics/extended_stats.c +++ b/src/backend/statistics/extended_stats.c @@ -2339,7 +2339,12 @@ build_expr_data(List *exprs, int stattarget) return exprdata; } -/* form an array of pg_statistic rows (per update_attstats) */ +/* + * Form an array of pg_statistic rows, one per expression. + * + * Each row is built the same way update_attstats() in analyze.c builds + * it, so keep the two in sync. + */ static Datum serialize_expr_stats(AnlExprData *exprdata, int nexprs) { @@ -2411,10 +2416,9 @@ serialize_expr_stats(AnlExprData *exprdata, int nexprs) i = Anum_pg_statistic_stanumbers1 - 1; for (k = 0; k < STATISTIC_NUM_SLOTS; k++) { - int nnum = stats->numnumbers[k]; - - if (nnum > 0) + if (stats->stanumbers[k] != NULL) { + int nnum = stats->numnumbers[k]; int n; Datum *numdatums = (Datum *) palloc(nnum * sizeof(Datum)); ArrayType *arry; @@ -2433,7 +2437,7 @@ serialize_expr_stats(AnlExprData *exprdata, int nexprs) i = Anum_pg_statistic_stavalues1 - 1; for (k = 0; k < STATISTIC_NUM_SLOTS; k++) { - if (stats->numvalues[k] > 0) + if (stats->stavalues[k] != NULL) { ArrayType *arry; -- 2.37.1 (Apple Git-137.1)