From adfe54235b355e4f0a904c17a78538f68b0d619b Mon Sep 17 00:00:00 2001
From: Maxime Schoemans <maxime.schoemans@enterprisedb.com>
Date: Thu, 4 Jun 2026 20:16:26 +0200
Subject: [PATCH v2 5/6] Let tuplesort_putindextuplevalues set the AM-reserved
 bit

Add a set_reserved_bit argument to tuplesort_putindextuplevalues that ORs
INDEX_AM_RESERVED_BIT into the formed tuple's t_info. The bit is preserved
through the sort and any tape spill, so an access method can mark tuples
before sorting and read the mark back when reading the sorted output.

No caller sets it yet (btree, hash and gist all pass false), so behavior is
unchanged. This is infrastructure for letting GiST's sorted build mark
multi-entry tuples, which the next commit uses.
---
 src/backend/access/gist/gistbuild.c        |  2 +-
 src/backend/access/hash/hashsort.c         |  2 +-
 src/backend/access/nbtree/nbtsort.c        |  2 +-
 src/backend/utils/sort/tuplesortvariants.c | 11 ++++++++++-
 src/include/utils/tuplesort.h              |  3 ++-
 5 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/src/backend/access/gist/gistbuild.c b/src/backend/access/gist/gistbuild.c
index ceb8d13ec91..6334bc6cdc8 100644
--- a/src/backend/access/gist/gistbuild.c
+++ b/src/backend/access/gist/gistbuild.c
@@ -396,7 +396,7 @@ gistSortedBuildCallback(Relation index,
 	tuplesort_putindextuplevalues(buildstate->sortstate,
 								  buildstate->indexrel,
 								  tid,
-								  compressed_values, isnull);
+								  compressed_values, isnull, false);
 
 	MemoryContextSwitchTo(oldCtx);
 	MemoryContextReset(buildstate->giststate->tempCxt);
diff --git a/src/backend/access/hash/hashsort.c b/src/backend/access/hash/hashsort.c
index 77bbfaa461b..9950f9c1c42 100644
--- a/src/backend/access/hash/hashsort.c
+++ b/src/backend/access/hash/hashsort.c
@@ -109,7 +109,7 @@ void
 _h_spool(HSpool *hspool, const ItemPointerData *self, const Datum *values, const bool *isnull)
 {
 	tuplesort_putindextuplevalues(hspool->sortstate, hspool->index,
-								  self, values, isnull);
+								  self, values, isnull, false);
 }
 
 /*
diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c
index 756dfa3dcf4..fbcb424d8fd 100644
--- a/src/backend/access/nbtree/nbtsort.c
+++ b/src/backend/access/nbtree/nbtsort.c
@@ -531,7 +531,7 @@ static void
 _bt_spool(BTSpool *btspool, const ItemPointerData *self, const Datum *values, const bool *isnull)
 {
 	tuplesort_putindextuplevalues(btspool->sortstate, btspool->index,
-								  self, values, isnull);
+								  self, values, isnull, false);
 }
 
 /*
diff --git a/src/backend/utils/sort/tuplesortvariants.c b/src/backend/utils/sort/tuplesortvariants.c
index 2509ac3e3a4..355cf98c565 100644
--- a/src/backend/utils/sort/tuplesortvariants.c
+++ b/src/backend/utils/sort/tuplesortvariants.c
@@ -834,7 +834,7 @@ tuplesort_putheaptuple(Tuplesortstate *state, HeapTuple tup)
 void
 tuplesort_putindextuplevalues(Tuplesortstate *state, Relation rel,
 							  const ItemPointerData *self, const Datum *values,
-							  const bool *isnull)
+							  const bool *isnull, bool set_reserved_bit)
 {
 	SortTuple	stup;
 	IndexTuple	tuple;
@@ -846,6 +846,15 @@ tuplesort_putindextuplevalues(Tuplesortstate *state, Relation rel,
 										  isnull, base->tuplecontext);
 	tuple = ((IndexTuple) stup.tuple);
 	tuple->t_tid = *self;
+
+	/*
+	 * Optionally set the AM-reserved bit in the tuple's t_info.  Its meaning
+	 * is defined by the access method; the bit is preserved through the sort
+	 * and any tape spill.
+	 */
+	if (set_reserved_bit)
+		tuple->t_info |= INDEX_AM_RESERVED_BIT;
+
 	/* set up first-column key value */
 	stup.datum1 = index_getattr(tuple,
 								1,
diff --git a/src/include/utils/tuplesort.h b/src/include/utils/tuplesort.h
index da68f45acf2..f5cc52d6bb7 100644
--- a/src/include/utils/tuplesort.h
+++ b/src/include/utils/tuplesort.h
@@ -426,7 +426,8 @@ extern void tuplesort_puttupleslot(Tuplesortstate *state,
 extern void tuplesort_putheaptuple(Tuplesortstate *state, HeapTuple tup);
 extern void tuplesort_putindextuplevalues(Tuplesortstate *state,
 										  Relation rel, const ItemPointerData *self,
-										  const Datum *values, const bool *isnull);
+										  const Datum *values, const bool *isnull,
+										  bool set_reserved_bit);
 extern void tuplesort_putbrintuple(Tuplesortstate *state, BrinTuple *tuple, Size size);
 extern void tuplesort_putgintuple(Tuplesortstate *state, GinTuple *tuple, Size size);
 extern void tuplesort_putdatum(Tuplesortstate *state, Datum val,
-- 
2.50.1 (Apple Git-155)

