From 8fe8176fa9fe62e4ff541154a2edc4f970a62acf Mon Sep 17 00:00:00 2001 From: Atish Prakash <125atishprak@gmail.com> Date: Sun, 8 Nov 2026 23:44:42 -0500 Subject: [PATCH v3 1/3] 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 518d7526255..ab3848443a7 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -1764,7 +1764,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 b66a49a6fb5..14652a36331 100644 --- a/src/backend/statistics/extended_stats.c +++ b/src/backend/statistics/extended_stats.c @@ -2333,7 +2333,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) { @@ -2405,10 +2410,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 = palloc_array(Datum, nnum); ArrayType *arry; @@ -2427,7 +2431,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)