From c60e9a5390908f25d97769f44728f3c905c3b96d Mon Sep 17 00:00:00 2001
From: Jan Nidzwetzki <jan@planetscale.com>
Date: Fri, 17 Jul 2026 21:41:23 +0200
Subject: [PATCH] Fix uninitialized tuple counts in parallel GIN index builds

_gin_parallel_build_main() sets up its GinBuildState on the stack but,
unlike ginbuild(), never initializes the bs_numtuples and bs_reltuples
counters.  bs_numtuples happens to be reset before use, but bs_reltuples
is not: _gin_parallel_scan_and_build() accumulates the worker's scanned
tuple count onto it with +=, so the worker publishes stack garbage
through the shared state.  The leader stores that total into
pg_class.reltuples via index_update_stats().

Initialize both counters in the worker, matching ginbuild().
---
 src/backend/access/gin/gininsert.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c
index cb9ed3b563c..cacaf1a105e 100644
--- a/src/backend/access/gin/gininsert.c
+++ b/src/backend/access/gin/gininsert.c
@@ -2161,6 +2161,10 @@ _gin_parallel_build_main(dsm_segment *seg, shm_toc *toc)
 	memset(&buildstate.buildStats, 0, sizeof(GinStatsData));
 	memset(&buildstate.tid, 0, sizeof(ItemPointerData));
 
+	/* Initialize counters used to report tuple counts to the leader. */
+	buildstate.bs_numtuples = 0;
+	buildstate.bs_reltuples = 0;
+
 	/*
 	 * create a temporary memory context that is used to hold data not yet
 	 * dumped out to the index
-- 
2.47.3

