From 7f4df2956c3e7940efec879237f8b79e8d8a76bd Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Tue, 12 Aug 2025 15:13:23 -0400
Subject: [PATCH v2 2/3] Grab the low-hanging fruit from forcing sizeof(Datum)
 to 8.

Remove conditionally-compiled code for smaller Datum widths.
I also fixed up a few more places that were not using
DatumGetIntXX where they should, and made some cosmetic
adjustments such as using sizeof(int64) not sizeof(Datum)
in places where that fit better with the surrounding code.

One thing I remembered while preparing this part is that SP-GiST
stores pass-by-value prefix keys as Datums, so that the on-disk
representation depends on sizeof(Datum).  That's even more
unfortunate than the existing commentary makes it out to be,
because now there is a hazard that the change of sizeof(Datum)
will break SP-GiST indexes on 32-bit machines.  It appears that
there are no existing SP-GiST opclasses that are actually
affected; and if there are some that I didn't find, the number
of installations that are using them on 32-bit machines is
doubtless tiny.  So I'm proceeding on the assumption that we
can get away with this, but it's something to worry about.

(gininsert.c looks like it has a similar problem, but it's okay
because the "tuples" it's constructing are just transient data
within the tuplesort step.  That's pretty poorly documented
though, so I added some comments.)

Discussion: https://postgr.es/m/1749799.1752797397@sss.pgh.pa.us
---
 doc/src/sgml/xfunc.sgml                |   3 +-
 src/backend/access/gin/gininsert.c     |   5 +-
 src/backend/access/gist/gistproc.c     |  10 +--
 src/backend/access/nbtree/nbtcompare.c |  20 -----
 src/backend/catalog/pg_type.c          |   4 +-
 src/backend/utils/adt/mac.c            |  27 +++----
 src/backend/utils/adt/network.c        |  14 +---
 src/backend/utils/adt/numeric.c        | 106 ++-----------------------
 src/backend/utils/adt/timestamp.c      |  21 -----
 src/backend/utils/adt/uuid.c           |   6 +-
 src/backend/utils/adt/varlena.c        |  12 +--
 src/backend/utils/sort/tuplesort.c     |   8 --
 src/include/access/gin_tuple.h         |   4 +-
 src/include/access/spgist_private.h    |  10 ++-
 src/include/access/tupmacs.h           |  12 +--
 src/include/port/pg_bswap.h            |  17 +---
 src/include/utils/sortsupport.h        |   4 -
 17 files changed, 50 insertions(+), 233 deletions(-)

diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml
index 30219f432d9..f116d0648e5 100644
--- a/doc/src/sgml/xfunc.sgml
+++ b/doc/src/sgml/xfunc.sgml
@@ -2051,8 +2051,7 @@ PG_MODULE_MAGIC_EXT(
     </para>
 
     <para>
-     By-value  types  can  only be 1, 2, or 4 bytes in length
-     (also 8 bytes, if <literal>sizeof(Datum)</literal> is 8 on your machine).
+     By-value types can only be 1, 2, 4, or 8 bytes in length.
      You should be careful to define your types such that they will be the
      same size (in bytes) on all architectures.  For example, the
      <literal>long</literal> type is dangerous because it is 4 bytes on some
diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c
index 47b1898a064..e9d4b27427e 100644
--- a/src/backend/access/gin/gininsert.c
+++ b/src/backend/access/gin/gininsert.c
@@ -2189,7 +2189,10 @@ typedef struct
  * we simply copy the whole Datum, so that we don't have to care about stuff
  * like endianess etc. We could make it a little bit smaller, but it's not
  * worth it - it's a tiny fraction of the data, and we need to MAXALIGN the
- * start of the TID list anyway. So we wouldn't save anything.
+ * start of the TID list anyway. So we wouldn't save anything. (This would
+ * not be a good idea for the permanent in-index data, since we'd prefer
+ * that that not depend on sizeof(Datum). But this is just a transient
+ * representation to use while sorting the data.)
  *
  * The TID list is serialized as compressed - it's highly compressible, and
  * we already have ginCompressPostingList for this purpose. The list may be
diff --git a/src/backend/access/gist/gistproc.c b/src/backend/access/gist/gistproc.c
index 392163cb229..f2ec6cbe2e5 100644
--- a/src/backend/access/gist/gistproc.c
+++ b/src/backend/access/gist/gistproc.c
@@ -1707,8 +1707,8 @@ gist_bbox_zorder_cmp(Datum a, Datum b, SortSupport ssup)
  * Abbreviated version of Z-order comparison
  *
  * The abbreviated format is a Z-order value computed from the two 32-bit
- * floats. If SIZEOF_DATUM == 8, the 64-bit Z-order value fits fully in the
- * abbreviated Datum, otherwise use its most significant bits.
+ * floats.  Now that sizeof(Datum) is always 8, the 64-bit Z-order value
+ * always fits fully in the abbreviated Datum.
  */
 static Datum
 gist_bbox_zorder_abbrev_convert(Datum original, SortSupport ssup)
@@ -1718,11 +1718,7 @@ gist_bbox_zorder_abbrev_convert(Datum original, SortSupport ssup)
 
 	z = point_zorder_internal(p->x, p->y);
 
-#if SIZEOF_DATUM == 8
-	return (Datum) z;
-#else
-	return (Datum) (z >> 32);
-#endif
+	return UInt64GetDatum(z);
 }
 
 /*
diff --git a/src/backend/access/nbtree/nbtcompare.c b/src/backend/access/nbtree/nbtcompare.c
index e1b52acd20d..188c27b4925 100644
--- a/src/backend/access/nbtree/nbtcompare.c
+++ b/src/backend/access/nbtree/nbtcompare.c
@@ -278,32 +278,12 @@ btint8cmp(PG_FUNCTION_ARGS)
 		PG_RETURN_INT32(A_LESS_THAN_B);
 }
 
-#if SIZEOF_DATUM < 8
-static int
-btint8fastcmp(Datum x, Datum y, SortSupport ssup)
-{
-	int64		a = DatumGetInt64(x);
-	int64		b = DatumGetInt64(y);
-
-	if (a > b)
-		return A_GREATER_THAN_B;
-	else if (a == b)
-		return 0;
-	else
-		return A_LESS_THAN_B;
-}
-#endif
-
 Datum
 btint8sortsupport(PG_FUNCTION_ARGS)
 {
 	SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
 
-#if SIZEOF_DATUM >= 8
 	ssup->comparator = ssup_datum_signed_cmp;
-#else
-	ssup->comparator = btint8fastcmp;
-#endif
 	PG_RETURN_VOID();
 }
 
diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c
index 1ec523ee3e5..3cd9b69edc5 100644
--- a/src/backend/catalog/pg_type.c
+++ b/src/backend/catalog/pg_type.c
@@ -285,8 +285,7 @@ TypeCreate(Oid newTypeOid,
 						 errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d",
 								alignment, internalSize)));
 		}
-#if SIZEOF_DATUM == 8
-		else if (internalSize == (int16) sizeof(Datum))
+		else if (internalSize == (int16) sizeof(int64))
 		{
 			if (alignment != TYPALIGN_DOUBLE)
 				ereport(ERROR,
@@ -294,7 +293,6 @@ TypeCreate(Oid newTypeOid,
 						 errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d",
 								alignment, internalSize)));
 		}
-#endif
 		else
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
diff --git a/src/backend/utils/adt/mac.c b/src/backend/utils/adt/mac.c
index 3644e9735f5..bb38ef2f5e4 100644
--- a/src/backend/utils/adt/mac.c
+++ b/src/backend/utils/adt/mac.c
@@ -481,33 +481,26 @@ macaddr_abbrev_convert(Datum original, SortSupport ssup)
 	Datum		res;
 
 	/*
-	 * On a 64-bit machine, zero out the 8-byte datum and copy the 6 bytes of
-	 * the MAC address in. There will be two bytes of zero padding on the end
-	 * of the least significant bits.
+	 * Zero out the 8-byte Datum and copy in the 6 bytes of the MAC address.
+	 * There will be two bytes of zero padding on the end of the least
+	 * significant bits.
 	 */
-#if SIZEOF_DATUM == 8
-	memset(&res, 0, SIZEOF_DATUM);
+	StaticAssertStmt(sizeof(res) >= sizeof(macaddr),
+					 "Datum is too small for macaddr");
+	memset(&res, 0, sizeof(res));
 	memcpy(&res, authoritative, sizeof(macaddr));
-#else							/* SIZEOF_DATUM != 8 */
-	memcpy(&res, authoritative, SIZEOF_DATUM);
-#endif
 	uss->input_count += 1;
 
 	/*
-	 * Cardinality estimation. The estimate uses uint32, so on a 64-bit
-	 * architecture, XOR the two 32-bit halves together to produce slightly
-	 * more entropy. The two zeroed bytes won't have any practical impact on
-	 * this operation.
+	 * Cardinality estimation. The estimate uses uint32, so XOR the two 32-bit
+	 * halves together to produce slightly more entropy. The two zeroed bytes
+	 * won't have any practical impact on this operation.
 	 */
 	if (uss->estimating)
 	{
 		uint32		tmp;
 
-#if SIZEOF_DATUM == 8
-		tmp = (uint32) res ^ (uint32) ((uint64) res >> 32);
-#else							/* SIZEOF_DATUM != 8 */
-		tmp = (uint32) res;
-#endif
+		tmp = DatumGetUInt32(res) ^ (uint32) (DatumGetUInt64(res) >> 32);
 
 		addHyperLogLog(&uss->abbr_card, DatumGetUInt32(hash_uint32(tmp)));
 	}
diff --git a/src/backend/utils/adt/network.c b/src/backend/utils/adt/network.c
index 9fd211b2d45..6e1ffee0655 100644
--- a/src/backend/utils/adt/network.c
+++ b/src/backend/utils/adt/network.c
@@ -659,7 +659,7 @@ network_abbrev_convert(Datum original, SortSupport ssup)
 		ipaddr_datum = DatumBigEndianToNative(ipaddr_datum);
 
 		/* Initialize result with ipfamily (most significant) bit set */
-		res = ((Datum) 1) << (SIZEOF_DATUM * BITS_PER_BYTE - 1);
+		res = ((Datum) 1) << (sizeof(Datum) * BITS_PER_BYTE - 1);
 	}
 
 	/*
@@ -681,14 +681,14 @@ network_abbrev_convert(Datum original, SortSupport ssup)
 	subnet_size = ip_maxbits(authoritative) - ip_bits(authoritative);
 	Assert(subnet_size >= 0);
 	/* subnet size must work with prefix ipaddr cases */
-	subnet_size %= SIZEOF_DATUM * BITS_PER_BYTE;
+	subnet_size %= sizeof(Datum) * BITS_PER_BYTE;
 	if (ip_bits(authoritative) == 0)
 	{
 		/* Fit as many ipaddr bits as possible into subnet */
 		subnet_bitmask = ((Datum) 0) - 1;
 		network = 0;
 	}
-	else if (ip_bits(authoritative) < SIZEOF_DATUM * BITS_PER_BYTE)
+	else if (ip_bits(authoritative) < sizeof(Datum) * BITS_PER_BYTE)
 	{
 		/* Split ipaddr bits between network and subnet */
 		subnet_bitmask = (((Datum) 1) << subnet_size) - 1;
@@ -701,7 +701,6 @@ network_abbrev_convert(Datum original, SortSupport ssup)
 		network = ipaddr_datum;
 	}
 
-#if SIZEOF_DATUM == 8
 	if (ip_family(authoritative) == PGSQL_AF_INET)
 	{
 		/*
@@ -750,7 +749,6 @@ network_abbrev_convert(Datum original, SortSupport ssup)
 		res |= network | netmask_size | subnet;
 	}
 	else
-#endif
 	{
 		/*
 		 * 4 byte datums, or IPv6 with 8 byte datums: Use as many of the
@@ -767,11 +765,7 @@ network_abbrev_convert(Datum original, SortSupport ssup)
 	{
 		uint32		tmp;
 
-#if SIZEOF_DATUM == 8
-		tmp = (uint32) res ^ (uint32) ((uint64) res >> 32);
-#else							/* SIZEOF_DATUM != 8 */
-		tmp = (uint32) res;
-#endif
+		tmp = DatumGetUInt32(res) ^ (uint32) (DatumGetUInt64(res) >> 32);
 
 		addHyperLogLog(&uss->abbr_card, DatumGetUInt32(hash_uint32(tmp)));
 	}
diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
index 122f2efab8b..4b94ee9a3b5 100644
--- a/src/backend/utils/adt/numeric.c
+++ b/src/backend/utils/adt/numeric.c
@@ -392,30 +392,21 @@ typedef struct NumericSumAccum
 
 /*
  * We define our own macros for packing and unpacking abbreviated-key
- * representations for numeric values in order to avoid depending on
- * USE_FLOAT8_BYVAL.  The type of abbreviation we use is based only on
- * the size of a datum, not the argument-passing convention for float8.
+ * representations, just to have a notational indication that that's
+ * what we're doing.  Now that sizeof(Datum) is always 8, we can rely
+ * on fitting an int64 into Datum.
  *
- * The range of abbreviations for finite values is from +PG_INT64/32_MAX
- * to -PG_INT64/32_MAX.  NaN has the abbreviation PG_INT64/32_MIN, and we
+ * The range of abbreviations for finite values is from +PG_INT64_MAX
+ * to -PG_INT64_MAX.  NaN has the abbreviation PG_INT64_MIN, and we
  * define the sort ordering to make that work out properly (see further
  * comments below).  PINF and NINF share the abbreviations of the largest
  * and smallest finite abbreviation classes.
  */
-#define NUMERIC_ABBREV_BITS (SIZEOF_DATUM * BITS_PER_BYTE)
-#if SIZEOF_DATUM == 8
-#define NumericAbbrevGetDatum(X) ((Datum) (X))
-#define DatumGetNumericAbbrev(X) ((int64) (X))
+#define NumericAbbrevGetDatum(X) Int64GetDatum(X)
+#define DatumGetNumericAbbrev(X) DatumGetInt64(X)
 #define NUMERIC_ABBREV_NAN		 NumericAbbrevGetDatum(PG_INT64_MIN)
 #define NUMERIC_ABBREV_PINF		 NumericAbbrevGetDatum(-PG_INT64_MAX)
 #define NUMERIC_ABBREV_NINF		 NumericAbbrevGetDatum(PG_INT64_MAX)
-#else
-#define NumericAbbrevGetDatum(X) ((Datum) (X))
-#define DatumGetNumericAbbrev(X) ((int32) (X))
-#define NUMERIC_ABBREV_NAN		 NumericAbbrevGetDatum(PG_INT32_MIN)
-#define NUMERIC_ABBREV_PINF		 NumericAbbrevGetDatum(-PG_INT32_MAX)
-#define NUMERIC_ABBREV_NINF		 NumericAbbrevGetDatum(PG_INT32_MAX)
-#endif
 
 
 /* ----------
@@ -2328,7 +2319,7 @@ numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup)
 }
 
 /*
- * Abbreviate a NumericVar according to the available bit size.
+ * Abbreviate a NumericVar into the 64-bit sortsupport size.
  *
  * The 31-bit value is constructed as:
  *
@@ -2372,9 +2363,6 @@ numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup)
  * with all bits zero. This allows simple comparisons to work on the composite
  * value.
  */
-
-#if NUMERIC_ABBREV_BITS == 64
-
 static Datum
 numeric_abbrev_convert_var(const NumericVar *var, NumericSortSupport *nss)
 {
@@ -2426,84 +2414,6 @@ numeric_abbrev_convert_var(const NumericVar *var, NumericSortSupport *nss)
 	return NumericAbbrevGetDatum(result);
 }
 
-#endif							/* NUMERIC_ABBREV_BITS == 64 */
-
-#if NUMERIC_ABBREV_BITS == 32
-
-static Datum
-numeric_abbrev_convert_var(const NumericVar *var, NumericSortSupport *nss)
-{
-	int			ndigits = var->ndigits;
-	int			weight = var->weight;
-	int32		result;
-
-	if (ndigits == 0 || weight < -11)
-	{
-		result = 0;
-	}
-	else if (weight > 20)
-	{
-		result = PG_INT32_MAX;
-	}
-	else
-	{
-		NumericDigit nxt1 = (ndigits > 1) ? var->digits[1] : 0;
-
-		weight = (weight + 11) * 4;
-
-		result = var->digits[0];
-
-		/*
-		 * "result" now has 1 to 4 nonzero decimal digits. We pack in more
-		 * digits to make 7 in total (largest we can fit in 24 bits)
-		 */
-
-		if (result > 999)
-		{
-			/* already have 4 digits, add 3 more */
-			result = (result * 1000) + (nxt1 / 10);
-			weight += 3;
-		}
-		else if (result > 99)
-		{
-			/* already have 3 digits, add 4 more */
-			result = (result * 10000) + nxt1;
-			weight += 2;
-		}
-		else if (result > 9)
-		{
-			NumericDigit nxt2 = (ndigits > 2) ? var->digits[2] : 0;
-
-			/* already have 2 digits, add 5 more */
-			result = (result * 100000) + (nxt1 * 10) + (nxt2 / 1000);
-			weight += 1;
-		}
-		else
-		{
-			NumericDigit nxt2 = (ndigits > 2) ? var->digits[2] : 0;
-
-			/* already have 1 digit, add 6 more */
-			result = (result * 1000000) + (nxt1 * 100) + (nxt2 / 100);
-		}
-
-		result = result | (weight << 24);
-	}
-
-	/* the abbrev is negated relative to the original */
-	if (var->sign == NUMERIC_POS)
-		result = -result;
-
-	if (nss->estimating)
-	{
-		uint32		tmp = (uint32) result;
-
-		addHyperLogLog(&nss->abbr_card, DatumGetUInt32(hash_uint32(tmp)));
-	}
-
-	return NumericAbbrevGetDatum(result);
-}
-
-#endif							/* NUMERIC_ABBREV_BITS == 32 */
 
 /*
  * Ordinary (non-sortsupport) comparisons follow.
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index e640b48205b..3e5f9dc1458 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -2275,33 +2275,12 @@ timestamp_cmp(PG_FUNCTION_ARGS)
 	PG_RETURN_INT32(timestamp_cmp_internal(dt1, dt2));
 }
 
-#if SIZEOF_DATUM < 8
-/* note: this is used for timestamptz also */
-static int
-timestamp_fastcmp(Datum x, Datum y, SortSupport ssup)
-{
-	Timestamp	a = DatumGetTimestamp(x);
-	Timestamp	b = DatumGetTimestamp(y);
-
-	return timestamp_cmp_internal(a, b);
-}
-#endif
-
 Datum
 timestamp_sortsupport(PG_FUNCTION_ARGS)
 {
 	SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
 
-#if SIZEOF_DATUM >= 8
-
-	/*
-	 * If this build has pass-by-value timestamps, then we can use a standard
-	 * comparator function.
-	 */
 	ssup->comparator = ssup_datum_signed_cmp;
-#else
-	ssup->comparator = timestamp_fastcmp;
-#endif
 	PG_RETURN_VOID();
 }
 
diff --git a/src/backend/utils/adt/uuid.c b/src/backend/utils/adt/uuid.c
index bce7309c183..7413239f7af 100644
--- a/src/backend/utils/adt/uuid.c
+++ b/src/backend/utils/adt/uuid.c
@@ -398,11 +398,7 @@ uuid_abbrev_convert(Datum original, SortSupport ssup)
 	{
 		uint32		tmp;
 
-#if SIZEOF_DATUM == 8
-		tmp = (uint32) res ^ (uint32) ((uint64) res >> 32);
-#else							/* SIZEOF_DATUM != 8 */
-		tmp = (uint32) res;
-#endif
+		tmp = DatumGetUInt32(res) ^ (uint32) (DatumGetUInt64(res) >> 32);
 
 		addHyperLogLog(&uss->abbr_card, DatumGetUInt32(hash_uint32(tmp)));
 	}
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index 11b442a5941..4fc3f0886a4 100644
--- a/src/backend/utils/adt/varlena.c
+++ b/src/backend/utils/adt/varlena.c
@@ -2132,18 +2132,12 @@ varstr_abbrev_convert(Datum original, SortSupport ssup)
 	addHyperLogLog(&sss->full_card, hash);
 
 	/* Hash abbreviated key */
-#if SIZEOF_DATUM == 8
 	{
-		uint32		lohalf,
-					hihalf;
+		uint32		tmp;
 
-		lohalf = (uint32) res;
-		hihalf = (uint32) (res >> 32);
-		hash = DatumGetUInt32(hash_uint32(lohalf ^ hihalf));
+		tmp = DatumGetUInt32(res) ^ (uint32) (DatumGetUInt64(res) >> 32);
+		hash = DatumGetUInt32(hash_uint32(tmp));
 	}
-#else							/* SIZEOF_DATUM != 8 */
-	hash = DatumGetUInt32(hash_uint32((uint32) res));
-#endif
 
 	addHyperLogLog(&sss->abbr_card, hash);
 
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index 65ab83fff8b..5d4411dc33f 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -512,7 +512,6 @@ qsort_tuple_unsigned_compare(SortTuple *a, SortTuple *b, Tuplesortstate *state)
 	return state->base.comparetup_tiebreak(a, b, state);
 }
 
-#if SIZEOF_DATUM >= 8
 /* Used if first key's comparator is ssup_datum_signed_cmp */
 static pg_attribute_always_inline int
 qsort_tuple_signed_compare(SortTuple *a, SortTuple *b, Tuplesortstate *state)
@@ -535,7 +534,6 @@ qsort_tuple_signed_compare(SortTuple *a, SortTuple *b, Tuplesortstate *state)
 
 	return state->base.comparetup_tiebreak(a, b, state);
 }
-#endif
 
 /* Used if first key's comparator is ssup_datum_int32_cmp */
 static pg_attribute_always_inline int
@@ -578,7 +576,6 @@ qsort_tuple_int32_compare(SortTuple *a, SortTuple *b, Tuplesortstate *state)
 #define ST_DEFINE
 #include "lib/sort_template.h"
 
-#if SIZEOF_DATUM >= 8
 #define ST_SORT qsort_tuple_signed
 #define ST_ELEMENT_TYPE SortTuple
 #define ST_COMPARE(a, b, state) qsort_tuple_signed_compare(a, b, state)
@@ -587,7 +584,6 @@ qsort_tuple_int32_compare(SortTuple *a, SortTuple *b, Tuplesortstate *state)
 #define ST_SCOPE static
 #define ST_DEFINE
 #include "lib/sort_template.h"
-#endif
 
 #define ST_SORT qsort_tuple_int32
 #define ST_ELEMENT_TYPE SortTuple
@@ -2692,7 +2688,6 @@ tuplesort_sort_memtuples(Tuplesortstate *state)
 									 state);
 				return;
 			}
-#if SIZEOF_DATUM >= 8
 			else if (state->base.sortKeys[0].comparator == ssup_datum_signed_cmp)
 			{
 				qsort_tuple_signed(state->memtuples,
@@ -2700,7 +2695,6 @@ tuplesort_sort_memtuples(Tuplesortstate *state)
 								   state);
 				return;
 			}
-#endif
 			else if (state->base.sortKeys[0].comparator == ssup_datum_int32_cmp)
 			{
 				qsort_tuple_int32(state->memtuples,
@@ -3146,7 +3140,6 @@ ssup_datum_unsigned_cmp(Datum x, Datum y, SortSupport ssup)
 		return 0;
 }
 
-#if SIZEOF_DATUM >= 8
 int
 ssup_datum_signed_cmp(Datum x, Datum y, SortSupport ssup)
 {
@@ -3160,7 +3153,6 @@ ssup_datum_signed_cmp(Datum x, Datum y, SortSupport ssup)
 	else
 		return 0;
 }
-#endif
 
 int
 ssup_datum_int32_cmp(Datum x, Datum y, SortSupport ssup)
diff --git a/src/include/access/gin_tuple.h b/src/include/access/gin_tuple.h
index 702f7d12889..b4f103dec9a 100644
--- a/src/include/access/gin_tuple.h
+++ b/src/include/access/gin_tuple.h
@@ -15,7 +15,9 @@
 #include "utils/sortsupport.h"
 
 /*
- * Data for one key in a GIN index.
+ * Data for one key in a GIN index.  (This is not the permanent in-index
+ * representation, but just a convenient format to use during the tuplesort
+ * stage of building a new GIN index.)
  */
 typedef struct GinTuple
 {
diff --git a/src/include/access/spgist_private.h b/src/include/access/spgist_private.h
index cb43a278f46..fdda7f4c639 100644
--- a/src/include/access/spgist_private.h
+++ b/src/include/access/spgist_private.h
@@ -285,10 +285,12 @@ typedef struct SpGistCache
  * If the prefix datum is of a pass-by-value type, it is stored in its
  * Datum representation, that is its on-disk representation is of length
  * sizeof(Datum).  This is a fairly unfortunate choice, because in no other
- * place does Postgres use Datum as an on-disk representation; it creates
- * an unnecessary incompatibility between 32-bit and 64-bit builds.  But the
- * compatibility loss is mostly theoretical since MAXIMUM_ALIGNOF typically
- * differs between such builds, too.  Anyway we're stuck with it now.
+ * place does Postgres use Datum as an on-disk representation.  Formerly it
+ * meant an unnecessary incompatibility between 32-bit and 64-bit builds, and
+ * as of v19 it instead creates a hazard for binary upgrades on 32-bit builds.
+ * Fortunately, that hazard seems mostly theoretical for lack of affected
+ * opclasses.  Going forward, we will be using a fixed size of Datum so that
+ * there's no longer any pressing reason to change this.
  */
 typedef struct SpGistInnerTupleData
 {
diff --git a/src/include/access/tupmacs.h b/src/include/access/tupmacs.h
index 6240ec930e7..3a05bf7ca66 100644
--- a/src/include/access/tupmacs.h
+++ b/src/include/access/tupmacs.h
@@ -62,10 +62,8 @@ fetch_att(const void *T, bool attbyval, int attlen)
 				return Int16GetDatum(*((const int16 *) T));
 			case sizeof(int32):
 				return Int32GetDatum(*((const int32 *) T));
-#if SIZEOF_DATUM == 8
-			case sizeof(Datum):
-				return *((const Datum *) T);
-#endif
+			case sizeof(int64):
+				return Int64GetDatum(*((const int64 *) T));
 			default:
 				elog(ERROR, "unsupported byval length: %d", attlen);
 				return 0;
@@ -221,11 +219,9 @@ store_att_byval(void *T, Datum newdatum, int attlen)
 		case sizeof(int32):
 			*(int32 *) T = DatumGetInt32(newdatum);
 			break;
-#if SIZEOF_DATUM == 8
-		case sizeof(Datum):
-			*(Datum *) T = newdatum;
+		case sizeof(int64):
+			*(int64 *) T = DatumGetInt64(newdatum);
 			break;
-#endif
 		default:
 			elog(ERROR, "unsupported byval length: %d", attlen);
 	}
diff --git a/src/include/port/pg_bswap.h b/src/include/port/pg_bswap.h
index 33648433c63..b15f6f6ac38 100644
--- a/src/include/port/pg_bswap.h
+++ b/src/include/port/pg_bswap.h
@@ -130,8 +130,7 @@ pg_bswap64(uint64 x)
 
 /*
  * Rearrange the bytes of a Datum from big-endian order into the native byte
- * order.  On big-endian machines, this does nothing at all.  Note that the C
- * type Datum is an unsigned integer type on all platforms.
+ * order.  On big-endian machines, this does nothing at all.
  *
  * One possible application of the DatumBigEndianToNative() macro is to make
  * bitwise comparisons cheaper.  A simple 3-way comparison of Datums
@@ -139,23 +138,11 @@ pg_bswap64(uint64 x)
  * the same result as a memcmp() of the corresponding original Datums, but can
  * be much cheaper.  It's generally safe to do this on big-endian systems
  * without any special transformation occurring first.
- *
- * If SIZEOF_DATUM is not defined, then postgres.h wasn't included and these
- * macros probably shouldn't be used, so we define nothing.  Note that
- * SIZEOF_DATUM == 8 would evaluate as 0 == 8 in that case, potentially
- * leading to the wrong implementation being selected and confusing errors, so
- * defining nothing is safest.
  */
-#ifdef SIZEOF_DATUM
 #ifdef WORDS_BIGENDIAN
 #define		DatumBigEndianToNative(x)	(x)
 #else							/* !WORDS_BIGENDIAN */
-#if SIZEOF_DATUM == 8
-#define		DatumBigEndianToNative(x)	pg_bswap64(x)
-#else							/* SIZEOF_DATUM != 8 */
-#define		DatumBigEndianToNative(x)	pg_bswap32(x)
-#endif							/* SIZEOF_DATUM == 8 */
+#define		DatumBigEndianToNative(x)	UInt64GetDatum(pg_bswap64(DatumGetUInt64(x)))
 #endif							/* WORDS_BIGENDIAN */
-#endif							/* SIZEOF_DATUM */
 
 #endif							/* PG_BSWAP_H */
diff --git a/src/include/utils/sortsupport.h b/src/include/utils/sortsupport.h
index b7abaf7802d..c64527e2ee9 100644
--- a/src/include/utils/sortsupport.h
+++ b/src/include/utils/sortsupport.h
@@ -262,7 +262,6 @@ ApplyUnsignedSortComparator(Datum datum1, bool isNull1,
 	return compare;
 }
 
-#if SIZEOF_DATUM >= 8
 static inline int
 ApplySignedSortComparator(Datum datum1, bool isNull1,
 						  Datum datum2, bool isNull2,
@@ -296,7 +295,6 @@ ApplySignedSortComparator(Datum datum1, bool isNull1,
 
 	return compare;
 }
-#endif
 
 static inline int
 ApplyInt32SortComparator(Datum datum1, bool isNull1,
@@ -376,9 +374,7 @@ ApplySortAbbrevFullComparator(Datum datum1, bool isNull1,
  * are eligible for faster sorting.
  */
 extern int	ssup_datum_unsigned_cmp(Datum x, Datum y, SortSupport ssup);
-#if SIZEOF_DATUM >= 8
 extern int	ssup_datum_signed_cmp(Datum x, Datum y, SortSupport ssup);
-#endif
 extern int	ssup_datum_int32_cmp(Datum x, Datum y, SortSupport ssup);
 
 /* Other functions in utils/sort/sortsupport.c */
-- 
2.43.7

