From e796b25bbd0765231307ec4c757f67bfdef9e363 Mon Sep 17 00:00:00 2001
From: reshke <reshke@double.cloud>
Date: Thu, 15 Jan 2026 06:34:42 +0000
Subject: [PATCH v3] Fix gistkillitems for GiST ROOT page.

GiST index killitems feature misbehaves for single-page
(ROOT-only) GiST index. This is caused by GiST scan
"current block" variable not beign initialized for
very first-to-scan page (which is ROOT page).
Fix this by moving variable initialization in
read pgae utility function. Also adjust test output
that used to test exactly this bug (starting 377b7ab).

Reviewed-by: Andrey Borodin <x4mmm@yandex-team.ru>
Reviewed-by: Soumya S Murali <soumyamurali.work@gmail.com>

Discussion: https://postgr.es/m/CALdSSPgZWX_D8%2BFx4YQqRN5eW5iSx_rJdqQhCfdWTvqKXVfJ4w%40mail.gmail.com
Discussion: https://postgr.es/m/lxzj26ga6ippdeunz6kuncectr5gfuugmm2ry22qu6hcx6oid6@lzx3sjsqhmt6
---
 src/backend/access/gist/gistget.c              | 6 +++---
 src/test/modules/index/expected/killtuples.out | 2 +-
 src/test/modules/index/specs/killtuples.spec   | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c
index 4d7c100d737..851d3679ce4 100644
--- a/src/backend/access/gist/gistget.c
+++ b/src/backend/access/gist/gistget.c
@@ -415,6 +415,9 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem,
 	 */
 	so->curPageLSN = BufferGetLSNAtomic(buffer);
 
+	/* save current item BlockNumber for gistkillitems() call */
+	so->curBlkno = pageItem->blkno;
+
 	/*
 	 * check all tuples on page
 	 */
@@ -730,9 +733,6 @@ gistgettuple(IndexScanDesc scan, ScanDirection dir)
 
 				CHECK_FOR_INTERRUPTS();
 
-				/* save current item BlockNumber for next gistkillitems() call */
-				so->curBlkno = item->blkno;
-
 				/*
 				 * While scanning a leaf page, ItemPointers of matching heap
 				 * tuples are stored in so->pageData.  If there are any on
diff --git a/src/test/modules/index/expected/killtuples.out b/src/test/modules/index/expected/killtuples.out
index a3db2c40936..1d944b493c2 100644
--- a/src/test/modules/index/expected/killtuples.out
+++ b/src/test/modules/index/expected/killtuples.out
@@ -223,7 +223,7 @@ step flush: SELECT FROM pg_stat_force_next_flush();
 step result: SELECT ((heap_blks_read + heap_blks_hit - counter.heap_accesses) > 0) AS has_new_heap_accesses FROM counter, pg_statio_all_tables WHERE relname = 'kill_prior_tuple';
 has_new_heap_accesses
 ---------------------
-t                    
+f                    
 (1 row)
 
 step drop_table: DROP TABLE IF EXISTS kill_prior_tuple;
diff --git a/src/test/modules/index/specs/killtuples.spec b/src/test/modules/index/specs/killtuples.spec
index 3b98ff9f76d..bd923c8bb00 100644
--- a/src/test/modules/index/specs/killtuples.spec
+++ b/src/test/modules/index/specs/killtuples.spec
@@ -96,7 +96,7 @@ permutation
   measure access flush result
   drop_table drop_ext_btree_gist
 
-# Test gist, but with fewer rows - shows that killitems doesn't work anymore!
+# Test gist, but with fewer rows - that killitems used to be buggy.
 permutation
   create_table fill_10 create_ext_btree_gist create_gist flush
   disable_seq disable_bitmap
-- 
2.25.1

