From 1d78e271b22d7c6a1557defbe15ea5039ff28510 Mon Sep 17 00:00:00 2001
From: Alexander Korotkov <akorotkov@postgresql.org>
Date: Tue, 21 Jun 2022 14:03:13 +0300
Subject: [PATCH v2 2/6] Tuplesortstate.getdatum1 method

Reported-by:
Bug:
Discussion:
Author:
Reviewed-by:
Tested-by:
Backpatch-through:
---
 src/backend/utils/sort/tuplesort.c | 100 ++++++++++++++++++-----------
 1 file changed, 64 insertions(+), 36 deletions(-)

diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index 0114855c83c..c649043fbb0 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -279,6 +279,8 @@ struct Tuplesortstate
 	 */
 	SortTupleComparator comparetup;
 
+	void		(*getdatum1) (Tuplesortstate *state, SortTuple *stup);
+
 	/*
 	 * Function to write a stored tuple onto tape.  The representation of the
 	 * tuple on tape need not be the same as it is in memory; requirements on
@@ -540,6 +542,7 @@ struct Sharedsort
 			pfree(buf); \
 	} while(0)
 
+#define GETDATUM1(state,stup)	((*(state)->getdatum1) (state, stup))
 #define COMPARETUP(state,a,b)	((*(state)->comparetup) (a, b, state))
 #define WRITETUP(state,tape,stup)	((*(state)->writetup) (state, tape, stup))
 #define READTUP(state,stup,tape,len) ((*(state)->readtup) (state, stup, tape, len))
@@ -629,6 +632,10 @@ static void reversedirection(Tuplesortstate *state);
 static unsigned int getlen(LogicalTape *tape, bool eofOK);
 static void markrunend(LogicalTape *tape);
 static void *readtup_alloc(Tuplesortstate *state, Size tuplen);
+static void getdatum1_heap(Tuplesortstate *state,  SortTuple *stup);
+static void getdatum1_cluster(Tuplesortstate *state,  SortTuple *stup);
+static void getdatum1_index(Tuplesortstate *state,  SortTuple *stup);
+static void getdatum1_datum(Tuplesortstate *state,  SortTuple *stup);
 static int	comparetup_heap(const SortTuple *a, const SortTuple *b,
 							Tuplesortstate *state);
 static void writetup_heap(Tuplesortstate *state, LogicalTape *tape,
@@ -1042,6 +1049,7 @@ tuplesort_begin_heap(TupleDesc tupDesc,
 								sortopt & TUPLESORT_RANDOMACCESS,
 								PARALLEL_SORT(state));
 
+	state->getdatum1 = getdatum1_heap;
 	state->comparetup = comparetup_heap;
 	state->writetup = writetup_heap;
 	state->readtup = readtup_heap;
@@ -1117,6 +1125,7 @@ tuplesort_begin_cluster(TupleDesc tupDesc,
 								sortopt & TUPLESORT_RANDOMACCESS,
 								PARALLEL_SORT(state));
 
+	state->getdatum1 = getdatum1_cluster;
 	state->comparetup = comparetup_cluster;
 	state->writetup = writetup_cluster;
 	state->readtup = readtup_cluster;
@@ -1221,6 +1230,7 @@ tuplesort_begin_index_btree(Relation heapRel,
 								sortopt & TUPLESORT_RANDOMACCESS,
 								PARALLEL_SORT(state));
 
+	state->getdatum1 = getdatum1_index;
 	state->comparetup = comparetup_index_btree;
 	state->writetup = writetup_index;
 	state->readtup = readtup_index;
@@ -1297,6 +1307,7 @@ tuplesort_begin_index_hash(Relation heapRel,
 
 	state->nKeys = 1;			/* Only one sort column, the hash code */
 
+	state->getdatum1 = getdatum1_index;
 	state->comparetup = comparetup_index_hash;
 	state->writetup = writetup_index;
 	state->readtup = readtup_index;
@@ -1337,6 +1348,7 @@ tuplesort_begin_index_gist(Relation heapRel,
 
 	state->nKeys = IndexRelationGetNumberOfKeyAttributes(indexRel);
 
+	state->getdatum1 = getdatum1_index;
 	state->comparetup = comparetup_index_btree;
 	state->writetup = writetup_index;
 	state->readtup = readtup_index;
@@ -1400,6 +1412,7 @@ tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation,
 								sortopt & TUPLESORT_RANDOMACCESS,
 								PARALLEL_SORT(state));
 
+	state->getdatum1 = getdatum1_datum;
 	state->comparetup = comparetup_datum;
 	state->writetup = writetup_datum;
 	state->readtup = readtup_datum;
@@ -1872,19 +1885,7 @@ tuplesort_puttupleslot(Tuplesortstate *state, TupleTableSlot *slot)
 		 * (TSS_BUILDRUNS state prevents control reaching here in any case).
 		 */
 		for (i = 0; i < state->memtupcount; i++)
-		{
-			SortTuple  *mtup = &state->memtuples[i];
-
-			htup.t_len = ((MinimalTuple) mtup->tuple)->t_len +
-				MINIMAL_TUPLE_OFFSET;
-			htup.t_data = (HeapTupleHeader) ((char *) mtup->tuple -
-											 MINIMAL_TUPLE_OFFSET);
-
-			mtup->datum1 = heap_getattr(&htup,
-										state->sortKeys[0].ssup_attno,
-										state->tupDesc,
-										&mtup->isnull1);
-		}
+			GETDATUM1(state, &state->memtuples[i]);
 	}
 
 	puttuple_common(state, &stup);
@@ -1957,15 +1958,7 @@ tuplesort_putheaptuple(Tuplesortstate *state, HeapTuple tup)
 			* (TSS_BUILDRUNS state prevents control reaching here in any case).
 			*/
 			for (i = 0; i < state->memtupcount; i++)
-			{
-				SortTuple  *mtup = &state->memtuples[i];
-
-				tup = (HeapTuple) mtup->tuple;
-				mtup->datum1 = heap_getattr(tup,
-											state->indexInfo->ii_IndexAttrNumbers[0],
-											state->tupDesc,
-											&mtup->isnull1);
-			}
+				GETDATUM1(state, &state->memtuples[i]);
 		}
 	}
 
@@ -2035,15 +2028,7 @@ tuplesort_putindextuplevalues(Tuplesortstate *state, Relation rel,
 		 * (TSS_BUILDRUNS state prevents control reaching here in any case).
 		 */
 		for (i = 0; i < state->memtupcount; i++)
-		{
-			SortTuple  *mtup = &state->memtuples[i];
-
-			tuple = mtup->tuple;
-			mtup->datum1 = index_getattr(tuple,
-										 1,
-										 RelationGetDescr(state->indexRel),
-										 &mtup->isnull1);
-		}
+			GETDATUM1(state, &state->memtuples[i]);
 	}
 
 	puttuple_common(state, &stup);
@@ -2122,11 +2107,7 @@ tuplesort_putdatum(Tuplesortstate *state, Datum val, bool isNull)
 			 * case).
 			 */
 			for (i = 0; i < state->memtupcount; i++)
-			{
-				SortTuple  *mtup = &state->memtuples[i];
-
-				mtup->datum1 = PointerGetDatum(mtup->tuple);
-			}
+				GETDATUM1(state, &state->memtuples[i]);
 		}
 	}
 
@@ -3983,6 +3964,23 @@ readtup_alloc(Tuplesortstate *state, Size tuplen)
  * Routines specialized for HeapTuple (actually MinimalTuple) case
  */
 
+static void
+getdatum1_heap(Tuplesortstate *state, SortTuple *stup)
+{
+	HeapTupleData htup;
+
+	htup.t_len = ((MinimalTuple) stup->tuple)->t_len +
+		MINIMAL_TUPLE_OFFSET;
+	htup.t_data = (HeapTupleHeader) ((char *) stup->tuple -
+										MINIMAL_TUPLE_OFFSET);
+
+	stup->datum1 = heap_getattr(&htup,
+								state->sortKeys[0].ssup_attno,
+								state->tupDesc,
+								&stup->isnull1);
+
+}
+
 static int
 comparetup_heap(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
 {
@@ -4101,6 +4099,18 @@ readtup_heap(Tuplesortstate *state, SortTuple *stup,
  * comparisons per a btree index definition)
  */
 
+static void
+getdatum1_cluster(Tuplesortstate *state, SortTuple *stup)
+{
+	HeapTuple tup;
+
+	tup = (HeapTuple) stup->tuple;
+	stup->datum1 = heap_getattr(tup,
+								state->indexInfo->ii_IndexAttrNumbers[0],
+								state->tupDesc,
+								&stup->isnull1);
+}
+
 static int
 comparetup_cluster(const SortTuple *a, const SortTuple *b,
 				   Tuplesortstate *state)
@@ -4270,6 +4280,18 @@ readtup_cluster(Tuplesortstate *state, SortTuple *stup,
  * functions can be shared.
  */
 
+static void
+getdatum1_index(Tuplesortstate *state, SortTuple *stup)
+{
+	IndexTuple	tuple;
+
+	tuple = stup->tuple;
+	stup->datum1 = index_getattr(tuple,
+								 1,
+								 RelationGetDescr(state->indexRel),
+								 &stup->isnull1);
+}
+
 static int
 comparetup_index_btree(const SortTuple *a, const SortTuple *b,
 					   Tuplesortstate *state)
@@ -4502,6 +4524,12 @@ readtup_index(Tuplesortstate *state, SortTuple *stup,
  * Routines specialized for DatumTuple case
  */
 
+static void
+getdatum1_datum(Tuplesortstate *state, SortTuple *stup)
+{
+	stup->datum1 = PointerGetDatum(stup->tuple);
+}
+
 static int
 comparetup_datum(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
 {
-- 
2.30.2

