From ee54046601de2d14ca9107ba04c50178d9b52fe6 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Wed, 13 Aug 2025 17:18:13 -0400
Subject: [PATCH] Grab the low-hanging fruit from forcing USE_FLOAT8_BYVAL to
 true.

Remove conditionally-compiled code for the other case.

Replace uses of FLOAT8PASSBYVAL with constant "true", mainly because
it was quite confusing in cases where the type we were dealing with
wasn't float8.

I left the associated pg_control and Pg_magic_struct fields in place.
Perhaps we should get rid of them, but it would save little, so it
doesn't seem worth thinking hard about the compatibility implications.
I just labeled them "vestigial" in places where that seemed helpful.

Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Peter Eisentraut <peter@eisentraut.org>
Discussion: https://postgr.es/m/1749799.1752797397@sss.pgh.pa.us
---
 contrib/btree_gist/btree_time.c               | 51 ++++++-------
 contrib/btree_gist/btree_ts.c                 | 39 ++++------
 src/backend/access/common/tupdesc.c           |  2 +-
 src/backend/access/index/indexam.c            |  5 --
 src/backend/access/transam/xlog.c             | 20 +----
 src/backend/catalog/genbki.pl                 |  3 +-
 src/backend/optimizer/plan/planagg.c          |  2 +-
 src/backend/optimizer/plan/planner.c          |  4 +-
 src/backend/parser/parse_node.c               |  2 +-
 src/backend/rewrite/rewriteSearchCycle.c      |  2 +-
 src/backend/utils/adt/arrayfuncs.c            |  6 +-
 src/backend/utils/adt/int8.c                  | 75 ++++---------------
 src/backend/utils/adt/numeric.c               | 74 ++++--------------
 src/backend/utils/adt/orderedsetaggs.c        |  2 +-
 src/backend/utils/adt/rangetypes_typanalyze.c |  2 +-
 src/backend/utils/fmgr/fmgr.c                 | 35 ---------
 src/bin/initdb/initdb.c                       |  3 -
 src/bin/pg_resetwal/pg_resetwal.c             |  2 +-
 src/include/c.h                               |  8 +-
 src/include/catalog/pg_type.dat               | 16 ++--
 src/include/fmgr.h                            |  2 +-
 src/include/postgres.h                        | 58 +-------------
 22 files changed, 100 insertions(+), 313 deletions(-)

diff --git a/contrib/btree_gist/btree_time.c b/contrib/btree_gist/btree_time.c
index 1dba95057b..fd6a2e05bc 100644
--- a/contrib/btree_gist/btree_time.c
+++ b/contrib/btree_gist/btree_time.c
@@ -31,13 +31,6 @@ PG_FUNCTION_INFO_V1(gbt_time_sortsupport);
 PG_FUNCTION_INFO_V1(gbt_timetz_sortsupport);
 
 
-#ifdef USE_FLOAT8_BYVAL
-#define TimeADTGetDatumFast(X) TimeADTGetDatum(X)
-#else
-#define TimeADTGetDatumFast(X) PointerGetDatum(&(X))
-#endif
-
-
 static bool
 gbt_timegt(const void *a, const void *b, FmgrInfo *flinfo)
 {
@@ -45,8 +38,8 @@ gbt_timegt(const void *a, const void *b, FmgrInfo *flinfo)
 	const TimeADT *bb = (const TimeADT *) b;
 
 	return DatumGetBool(DirectFunctionCall2(time_gt,
-											TimeADTGetDatumFast(*aa),
-											TimeADTGetDatumFast(*bb)));
+											TimeADTGetDatum(*aa),
+											TimeADTGetDatum(*bb)));
 }
 
 static bool
@@ -56,8 +49,8 @@ gbt_timege(const void *a, const void *b, FmgrInfo *flinfo)
 	const TimeADT *bb = (const TimeADT *) b;
 
 	return DatumGetBool(DirectFunctionCall2(time_ge,
-											TimeADTGetDatumFast(*aa),
-											TimeADTGetDatumFast(*bb)));
+											TimeADTGetDatum(*aa),
+											TimeADTGetDatum(*bb)));
 }
 
 static bool
@@ -67,8 +60,8 @@ gbt_timeeq(const void *a, const void *b, FmgrInfo *flinfo)
 	const TimeADT *bb = (const TimeADT *) b;
 
 	return DatumGetBool(DirectFunctionCall2(time_eq,
-											TimeADTGetDatumFast(*aa),
-											TimeADTGetDatumFast(*bb)));
+											TimeADTGetDatum(*aa),
+											TimeADTGetDatum(*bb)));
 }
 
 static bool
@@ -78,8 +71,8 @@ gbt_timele(const void *a, const void *b, FmgrInfo *flinfo)
 	const TimeADT *bb = (const TimeADT *) b;
 
 	return DatumGetBool(DirectFunctionCall2(time_le,
-											TimeADTGetDatumFast(*aa),
-											TimeADTGetDatumFast(*bb)));
+											TimeADTGetDatum(*aa),
+											TimeADTGetDatum(*bb)));
 }
 
 static bool
@@ -89,8 +82,8 @@ gbt_timelt(const void *a, const void *b, FmgrInfo *flinfo)
 	const TimeADT *bb = (const TimeADT *) b;
 
 	return DatumGetBool(DirectFunctionCall2(time_lt,
-											TimeADTGetDatumFast(*aa),
-											TimeADTGetDatumFast(*bb)));
+											TimeADTGetDatum(*aa),
+											TimeADTGetDatum(*bb)));
 }
 
 static int
@@ -100,9 +93,9 @@ gbt_timekey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 	timeKEY    *ib = (timeKEY *) (((const Nsrt *) b)->t);
 	int			res;
 
-	res = DatumGetInt32(DirectFunctionCall2(time_cmp, TimeADTGetDatumFast(ia->lower), TimeADTGetDatumFast(ib->lower)));
+	res = DatumGetInt32(DirectFunctionCall2(time_cmp, TimeADTGetDatum(ia->lower), TimeADTGetDatum(ib->lower)));
 	if (res == 0)
-		return DatumGetInt32(DirectFunctionCall2(time_cmp, TimeADTGetDatumFast(ia->upper), TimeADTGetDatumFast(ib->upper)));
+		return DatumGetInt32(DirectFunctionCall2(time_cmp, TimeADTGetDatum(ia->upper), TimeADTGetDatum(ib->upper)));
 
 	return res;
 }
@@ -115,8 +108,8 @@ gbt_time_dist(const void *a, const void *b, FmgrInfo *flinfo)
 	Interval   *i;
 
 	i = DatumGetIntervalP(DirectFunctionCall2(time_mi_time,
-											  TimeADTGetDatumFast(*aa),
-											  TimeADTGetDatumFast(*bb)));
+											  TimeADTGetDatum(*aa),
+											  TimeADTGetDatum(*bb)));
 	return fabs(INTERVAL_TO_SEC(i));
 }
 
@@ -279,14 +272,14 @@ gbt_time_penalty(PG_FUNCTION_ARGS)
 	double		res2;
 
 	intr = DatumGetIntervalP(DirectFunctionCall2(time_mi_time,
-												 TimeADTGetDatumFast(newentry->upper),
-												 TimeADTGetDatumFast(origentry->upper)));
+												 TimeADTGetDatum(newentry->upper),
+												 TimeADTGetDatum(origentry->upper)));
 	res = INTERVAL_TO_SEC(intr);
 	res = Max(res, 0);
 
 	intr = DatumGetIntervalP(DirectFunctionCall2(time_mi_time,
-												 TimeADTGetDatumFast(origentry->lower),
-												 TimeADTGetDatumFast(newentry->lower)));
+												 TimeADTGetDatum(origentry->lower),
+												 TimeADTGetDatum(newentry->lower)));
 	res2 = INTERVAL_TO_SEC(intr);
 	res2 = Max(res2, 0);
 
@@ -297,8 +290,8 @@ gbt_time_penalty(PG_FUNCTION_ARGS)
 	if (res > 0)
 	{
 		intr = DatumGetIntervalP(DirectFunctionCall2(time_mi_time,
-													 TimeADTGetDatumFast(origentry->upper),
-													 TimeADTGetDatumFast(origentry->lower)));
+													 TimeADTGetDatum(origentry->upper),
+													 TimeADTGetDatum(origentry->lower)));
 		*result += FLT_MIN;
 		*result += (float) (res / (res + INTERVAL_TO_SEC(intr)));
 		*result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
@@ -334,8 +327,8 @@ gbt_timekey_ssup_cmp(Datum x, Datum y, SortSupport ssup)
 
 	/* for leaf items we expect lower == upper, so only compare lower */
 	return DatumGetInt32(DirectFunctionCall2(time_cmp,
-											 TimeADTGetDatumFast(arg1->lower),
-											 TimeADTGetDatumFast(arg2->lower)));
+											 TimeADTGetDatum(arg1->lower),
+											 TimeADTGetDatum(arg2->lower)));
 }
 
 Datum
diff --git a/contrib/btree_gist/btree_ts.c b/contrib/btree_gist/btree_ts.c
index eb899c4d21..1e8f83f0f0 100644
--- a/contrib/btree_gist/btree_ts.c
+++ b/contrib/btree_gist/btree_ts.c
@@ -33,13 +33,6 @@ PG_FUNCTION_INFO_V1(gbt_ts_same);
 PG_FUNCTION_INFO_V1(gbt_ts_sortsupport);
 
 
-#ifdef USE_FLOAT8_BYVAL
-#define TimestampGetDatumFast(X) TimestampGetDatum(X)
-#else
-#define TimestampGetDatumFast(X) PointerGetDatum(&(X))
-#endif
-
-
 /* define for comparison */
 
 static bool
@@ -49,8 +42,8 @@ gbt_tsgt(const void *a, const void *b, FmgrInfo *flinfo)
 	const Timestamp *bb = (const Timestamp *) b;
 
 	return DatumGetBool(DirectFunctionCall2(timestamp_gt,
-											TimestampGetDatumFast(*aa),
-											TimestampGetDatumFast(*bb)));
+											TimestampGetDatum(*aa),
+											TimestampGetDatum(*bb)));
 }
 
 static bool
@@ -60,8 +53,8 @@ gbt_tsge(const void *a, const void *b, FmgrInfo *flinfo)
 	const Timestamp *bb = (const Timestamp *) b;
 
 	return DatumGetBool(DirectFunctionCall2(timestamp_ge,
-											TimestampGetDatumFast(*aa),
-											TimestampGetDatumFast(*bb)));
+											TimestampGetDatum(*aa),
+											TimestampGetDatum(*bb)));
 }
 
 static bool
@@ -71,8 +64,8 @@ gbt_tseq(const void *a, const void *b, FmgrInfo *flinfo)
 	const Timestamp *bb = (const Timestamp *) b;
 
 	return DatumGetBool(DirectFunctionCall2(timestamp_eq,
-											TimestampGetDatumFast(*aa),
-											TimestampGetDatumFast(*bb)));
+											TimestampGetDatum(*aa),
+											TimestampGetDatum(*bb)));
 }
 
 static bool
@@ -82,8 +75,8 @@ gbt_tsle(const void *a, const void *b, FmgrInfo *flinfo)
 	const Timestamp *bb = (const Timestamp *) b;
 
 	return DatumGetBool(DirectFunctionCall2(timestamp_le,
-											TimestampGetDatumFast(*aa),
-											TimestampGetDatumFast(*bb)));
+											TimestampGetDatum(*aa),
+											TimestampGetDatum(*bb)));
 }
 
 static bool
@@ -93,8 +86,8 @@ gbt_tslt(const void *a, const void *b, FmgrInfo *flinfo)
 	const Timestamp *bb = (const Timestamp *) b;
 
 	return DatumGetBool(DirectFunctionCall2(timestamp_lt,
-											TimestampGetDatumFast(*aa),
-											TimestampGetDatumFast(*bb)));
+											TimestampGetDatum(*aa),
+											TimestampGetDatum(*bb)));
 }
 
 static int
@@ -104,9 +97,9 @@ gbt_tskey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 	tsKEY	   *ib = (tsKEY *) (((const Nsrt *) b)->t);
 	int			res;
 
-	res = DatumGetInt32(DirectFunctionCall2(timestamp_cmp, TimestampGetDatumFast(ia->lower), TimestampGetDatumFast(ib->lower)));
+	res = DatumGetInt32(DirectFunctionCall2(timestamp_cmp, TimestampGetDatum(ia->lower), TimestampGetDatum(ib->lower)));
 	if (res == 0)
-		return DatumGetInt32(DirectFunctionCall2(timestamp_cmp, TimestampGetDatumFast(ia->upper), TimestampGetDatumFast(ib->upper)));
+		return DatumGetInt32(DirectFunctionCall2(timestamp_cmp, TimestampGetDatum(ia->upper), TimestampGetDatum(ib->upper)));
 
 	return res;
 }
@@ -122,8 +115,8 @@ gbt_ts_dist(const void *a, const void *b, FmgrInfo *flinfo)
 		return get_float8_infinity();
 
 	i = DatumGetIntervalP(DirectFunctionCall2(timestamp_mi,
-											  TimestampGetDatumFast(*aa),
-											  TimestampGetDatumFast(*bb)));
+											  TimestampGetDatum(*aa),
+											  TimestampGetDatum(*bb)));
 	return fabs(INTERVAL_TO_SEC(i));
 }
 
@@ -404,8 +397,8 @@ gbt_ts_ssup_cmp(Datum x, Datum y, SortSupport ssup)
 
 	/* for leaf items we expect lower == upper, so only compare lower */
 	return DatumGetInt32(DirectFunctionCall2(timestamp_cmp,
-											 TimestampGetDatumFast(arg1->lower),
-											 TimestampGetDatumFast(arg2->lower)));
+											 TimestampGetDatum(arg1->lower),
+											 TimestampGetDatum(arg2->lower)));
 }
 
 Datum
diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c
index be60005ae4..568edacb9b 100644
--- a/src/backend/access/common/tupdesc.c
+++ b/src/backend/access/common/tupdesc.c
@@ -993,7 +993,7 @@ TupleDescInitBuiltinEntry(TupleDesc desc,
 
 		case INT8OID:
 			att->attlen = 8;
-			att->attbyval = FLOAT8PASSBYVAL;
+			att->attbyval = true;
 			att->attalign = TYPALIGN_DOUBLE;
 			att->attstorage = TYPSTORAGE_PLAIN;
 			att->attcompression = InvalidCompressionMethod;
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index 219df1971d..1a4f36fe0a 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -986,11 +986,6 @@ index_store_float8_orderby_distances(IndexScanDesc scan, Oid *orderByTypes,
 	{
 		if (orderByTypes[i] == FLOAT8OID)
 		{
-#ifndef USE_FLOAT8_BYVAL
-			/* must free any old value to avoid memory leakage */
-			if (!scan->xs_orderbynulls[i])
-				pfree(DatumGetPointer(scan->xs_orderbyvals[i]));
-#endif
 			if (distances && !distances[i].isnull)
 			{
 				scan->xs_orderbyvals[i] = Float8GetDatum(distances[i].value);
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 9a4de1616b..e890940668 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -4390,7 +4390,7 @@ WriteControlFile(void)
 	ControlFile->toast_max_chunk_size = TOAST_MAX_CHUNK_SIZE;
 	ControlFile->loblksize = LOBLKSIZE;
 
-	ControlFile->float8ByVal = FLOAT8PASSBYVAL;
+	ControlFile->float8ByVal = true;	/* vestigial */
 
 	/*
 	 * Initialize the default 'char' signedness.
@@ -4651,23 +4651,7 @@ ReadControlFile(void)
 						   "LOBLKSIZE", (int) LOBLKSIZE),
 				 errhint("It looks like you need to recompile or initdb.")));
 
-#ifdef USE_FLOAT8_BYVAL
-	if (ControlFile->float8ByVal != true)
-		ereport(FATAL,
-				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
-				 errmsg("database files are incompatible with server"),
-				 errdetail("The database cluster was initialized without USE_FLOAT8_BYVAL"
-						   " but the server was compiled with USE_FLOAT8_BYVAL."),
-				 errhint("It looks like you need to recompile or initdb.")));
-#else
-	if (ControlFile->float8ByVal != false)
-		ereport(FATAL,
-				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
-				 errmsg("database files are incompatible with server"),
-				 errdetail("The database cluster was initialized with USE_FLOAT8_BYVAL"
-						   " but the server was compiled without USE_FLOAT8_BYVAL."),
-				 errhint("It looks like you need to recompile or initdb.")));
-#endif
+	Assert(ControlFile->float8ByVal);	/* vestigial, not worth an error msg */
 
 	wal_segment_size = ControlFile->xlog_seg_size;
 
diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl
index df3231fcd4..6c02aee726 100644
--- a/src/backend/catalog/genbki.pl
+++ b/src/backend/catalog/genbki.pl
@@ -1054,8 +1054,7 @@ sub morph_row_for_schemapg
 		}
 
 		# Expand booleans from 'f'/'t' to 'false'/'true'.
-		# Some values might be other macros (eg FLOAT8PASSBYVAL),
-		# don't change.
+		# Some values might be other macros, if so don't change.
 		elsif ($atttype eq 'bool')
 		{
 			$row->{$attname} = 'true' if $row->{$attname} eq 't';
diff --git a/src/backend/optimizer/plan/planagg.c b/src/backend/optimizer/plan/planagg.c
index 64605be317..2ef0bb7f66 100644
--- a/src/backend/optimizer/plan/planagg.c
+++ b/src/backend/optimizer/plan/planagg.c
@@ -410,7 +410,7 @@ build_minmax_path(PlannerInfo *root, MinMaxAggInfo *mminfo,
 	parse->limitCount = (Node *) makeConst(INT8OID, -1, InvalidOid,
 										   sizeof(int64),
 										   Int64GetDatum(1), false,
-										   FLOAT8PASSBYVAL);
+										   true);
 
 	/*
 	 * Generate the best paths for this query, telling query_planner that we
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 5ba0d22bef..0d5a692e5f 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -4915,7 +4915,7 @@ create_partial_distinct_paths(PlannerInfo *root, RelOptInfo *input_rel,
 					limitCount = (Node *) makeConst(INT8OID, -1, InvalidOid,
 													sizeof(int64),
 													Int64GetDatum(1), false,
-													FLOAT8PASSBYVAL);
+													true);
 
 					/*
 					 * Apply a LimitPath onto the partial path to restrict the
@@ -5118,7 +5118,7 @@ create_final_distinct_paths(PlannerInfo *root, RelOptInfo *input_rel,
 					limitCount = (Node *) makeConst(INT8OID, -1, InvalidOid,
 													sizeof(int64),
 													Int64GetDatum(1), false,
-													FLOAT8PASSBYVAL);
+													true);
 
 					/*
 					 * If the query already has a LIMIT clause, then we could
diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c
index d6feb16aef..203b7a3217 100644
--- a/src/backend/parser/parse_node.c
+++ b/src/backend/parser/parse_node.c
@@ -408,7 +408,7 @@ make_const(ParseState *pstate, A_Const *aconst)
 
 						typeid = INT8OID;
 						typelen = sizeof(int64);
-						typebyval = FLOAT8PASSBYVAL;	/* int8 and float8 alike */
+						typebyval = true;
 					}
 				}
 				else
diff --git a/src/backend/rewrite/rewriteSearchCycle.c b/src/backend/rewrite/rewriteSearchCycle.c
index 19b89dee0d..9f95d4dc1b 100644
--- a/src/backend/rewrite/rewriteSearchCycle.c
+++ b/src/backend/rewrite/rewriteSearchCycle.c
@@ -320,7 +320,7 @@ rewriteSearchAndCycle(CommonTableExpr *cte)
 		if (cte->search_clause->search_breadth_first)
 		{
 			search_col_rowexpr->args = lcons(makeConst(INT8OID, -1, InvalidOid, sizeof(int64),
-													   Int64GetDatum(0), false, FLOAT8PASSBYVAL),
+													   Int64GetDatum(0), false, true),
 											 search_col_rowexpr->args);
 			search_col_rowexpr->colnames = lcons(makeString("*DEPTH*"), search_col_rowexpr->colnames);
 			texpr = (Expr *) search_col_rowexpr;
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index c8f53c6fbe..c833e7df1f 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -3406,7 +3406,7 @@ construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
 
 		case FLOAT8OID:
 			elmlen = sizeof(float8);
-			elmbyval = FLOAT8PASSBYVAL;
+			elmbyval = true;
 			elmalign = TYPALIGN_DOUBLE;
 			break;
 
@@ -3424,7 +3424,7 @@ construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
 
 		case INT8OID:
 			elmlen = sizeof(int64);
-			elmbyval = FLOAT8PASSBYVAL;
+			elmbyval = true;
 			elmalign = TYPALIGN_DOUBLE;
 			break;
 
@@ -3718,7 +3718,7 @@ deconstruct_array_builtin(ArrayType *array,
 
 		case FLOAT8OID:
 			elmlen = sizeof(float8);
-			elmbyval = FLOAT8PASSBYVAL;
+			elmbyval = true;
 			elmalign = TYPALIGN_DOUBLE;
 			break;
 
diff --git a/src/backend/utils/adt/int8.c b/src/backend/utils/adt/int8.c
index 9dd5889f34..bdea490202 100644
--- a/src/backend/utils/adt/int8.c
+++ b/src/backend/utils/adt/int8.c
@@ -718,76 +718,29 @@ int8lcm(PG_FUNCTION_ARGS)
 Datum
 int8inc(PG_FUNCTION_ARGS)
 {
-	/*
-	 * When int8 is pass-by-reference, we provide this special case to avoid
-	 * palloc overhead for COUNT(): when called as an aggregate, we know that
-	 * the argument is modifiable local storage, so just update it in-place.
-	 * (If int8 is pass-by-value, then of course this is useless as well as
-	 * incorrect, so just ifdef it out.)
-	 */
-#ifndef USE_FLOAT8_BYVAL		/* controls int8 too */
-	if (AggCheckCallContext(fcinfo, NULL))
-	{
-		int64	   *arg = (int64 *) PG_GETARG_POINTER(0);
-
-		if (unlikely(pg_add_s64_overflow(*arg, 1, arg)))
-			ereport(ERROR,
-					(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-					 errmsg("bigint out of range")));
-
-		PG_RETURN_POINTER(arg);
-	}
-	else
-#endif
-	{
-		/* Not called as an aggregate, so just do it the dumb way */
-		int64		arg = PG_GETARG_INT64(0);
-		int64		result;
+	int64		arg = PG_GETARG_INT64(0);
+	int64		result;
 
-		if (unlikely(pg_add_s64_overflow(arg, 1, &result)))
-			ereport(ERROR,
-					(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-					 errmsg("bigint out of range")));
+	if (unlikely(pg_add_s64_overflow(arg, 1, &result)))
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("bigint out of range")));
 
-		PG_RETURN_INT64(result);
-	}
+	PG_RETURN_INT64(result);
 }
 
 Datum
 int8dec(PG_FUNCTION_ARGS)
 {
-	/*
-	 * When int8 is pass-by-reference, we provide this special case to avoid
-	 * palloc overhead for COUNT(): when called as an aggregate, we know that
-	 * the argument is modifiable local storage, so just update it in-place.
-	 * (If int8 is pass-by-value, then of course this is useless as well as
-	 * incorrect, so just ifdef it out.)
-	 */
-#ifndef USE_FLOAT8_BYVAL		/* controls int8 too */
-	if (AggCheckCallContext(fcinfo, NULL))
-	{
-		int64	   *arg = (int64 *) PG_GETARG_POINTER(0);
-
-		if (unlikely(pg_sub_s64_overflow(*arg, 1, arg)))
-			ereport(ERROR,
-					(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-					 errmsg("bigint out of range")));
-		PG_RETURN_POINTER(arg);
-	}
-	else
-#endif
-	{
-		/* Not called as an aggregate, so just do it the dumb way */
-		int64		arg = PG_GETARG_INT64(0);
-		int64		result;
+	int64		arg = PG_GETARG_INT64(0);
+	int64		result;
 
-		if (unlikely(pg_sub_s64_overflow(arg, 1, &result)))
-			ereport(ERROR,
-					(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-					 errmsg("bigint out of range")));
+	if (unlikely(pg_sub_s64_overflow(arg, 1, &result)))
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("bigint out of range")));
 
-		PG_RETURN_INT64(result);
-	}
+	PG_RETURN_INT64(result);
 }
 
 
diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
index a79aea5f78..b6287f5d97 100644
--- a/src/backend/utils/adt/numeric.c
+++ b/src/backend/utils/adt/numeric.c
@@ -6362,6 +6362,7 @@ numeric_poly_stddev_pop(PG_FUNCTION_ARGS)
 Datum
 int2_sum(PG_FUNCTION_ARGS)
 {
+	int64		oldsum;
 	int64		newval;
 
 	if (PG_ARGISNULL(0))
@@ -6374,43 +6375,22 @@ int2_sum(PG_FUNCTION_ARGS)
 		PG_RETURN_INT64(newval);
 	}
 
-	/*
-	 * If we're invoked as an aggregate, we can cheat and modify our first
-	 * parameter in-place to avoid palloc overhead. If not, we need to return
-	 * the new value of the transition variable. (If int8 is pass-by-value,
-	 * then of course this is useless as well as incorrect, so just ifdef it
-	 * out.)
-	 */
-#ifndef USE_FLOAT8_BYVAL		/* controls int8 too */
-	if (AggCheckCallContext(fcinfo, NULL))
-	{
-		int64	   *oldsum = (int64 *) PG_GETARG_POINTER(0);
+	oldsum = PG_GETARG_INT64(0);
 
-		/* Leave the running sum unchanged in the new input is null */
-		if (!PG_ARGISNULL(1))
-			*oldsum = *oldsum + (int64) PG_GETARG_INT16(1);
-
-		PG_RETURN_POINTER(oldsum);
-	}
-	else
-#endif
-	{
-		int64		oldsum = PG_GETARG_INT64(0);
-
-		/* Leave sum unchanged if new input is null. */
-		if (PG_ARGISNULL(1))
-			PG_RETURN_INT64(oldsum);
+	/* Leave sum unchanged if new input is null. */
+	if (PG_ARGISNULL(1))
+		PG_RETURN_INT64(oldsum);
 
-		/* OK to do the addition. */
-		newval = oldsum + (int64) PG_GETARG_INT16(1);
+	/* OK to do the addition. */
+	newval = oldsum + (int64) PG_GETARG_INT16(1);
 
-		PG_RETURN_INT64(newval);
-	}
+	PG_RETURN_INT64(newval);
 }
 
 Datum
 int4_sum(PG_FUNCTION_ARGS)
 {
+	int64		oldsum;
 	int64		newval;
 
 	if (PG_ARGISNULL(0))
@@ -6423,38 +6403,16 @@ int4_sum(PG_FUNCTION_ARGS)
 		PG_RETURN_INT64(newval);
 	}
 
-	/*
-	 * If we're invoked as an aggregate, we can cheat and modify our first
-	 * parameter in-place to avoid palloc overhead. If not, we need to return
-	 * the new value of the transition variable. (If int8 is pass-by-value,
-	 * then of course this is useless as well as incorrect, so just ifdef it
-	 * out.)
-	 */
-#ifndef USE_FLOAT8_BYVAL		/* controls int8 too */
-	if (AggCheckCallContext(fcinfo, NULL))
-	{
-		int64	   *oldsum = (int64 *) PG_GETARG_POINTER(0);
+	oldsum = PG_GETARG_INT64(0);
 
-		/* Leave the running sum unchanged in the new input is null */
-		if (!PG_ARGISNULL(1))
-			*oldsum = *oldsum + (int64) PG_GETARG_INT32(1);
-
-		PG_RETURN_POINTER(oldsum);
-	}
-	else
-#endif
-	{
-		int64		oldsum = PG_GETARG_INT64(0);
-
-		/* Leave sum unchanged if new input is null. */
-		if (PG_ARGISNULL(1))
-			PG_RETURN_INT64(oldsum);
+	/* Leave sum unchanged if new input is null. */
+	if (PG_ARGISNULL(1))
+		PG_RETURN_INT64(oldsum);
 
-		/* OK to do the addition. */
-		newval = oldsum + (int64) PG_GETARG_INT32(1);
+	/* OK to do the addition. */
+	newval = oldsum + (int64) PG_GETARG_INT32(1);
 
-		PG_RETURN_INT64(newval);
-	}
+	PG_RETURN_INT64(newval);
 }
 
 /*
diff --git a/src/backend/utils/adt/orderedsetaggs.c b/src/backend/utils/adt/orderedsetaggs.c
index 9457d23971..c41b191be6 100644
--- a/src/backend/utils/adt/orderedsetaggs.c
+++ b/src/backend/utils/adt/orderedsetaggs.c
@@ -1007,7 +1007,7 @@ percentile_cont_float8_multi_final(PG_FUNCTION_ARGS)
 											  FLOAT8OID,
 	/* hard-wired info on type float8 */
 											  sizeof(float8),
-											  FLOAT8PASSBYVAL,
+											  true,
 											  TYPALIGN_DOUBLE,
 											  float8_lerp);
 }
diff --git a/src/backend/utils/adt/rangetypes_typanalyze.c b/src/backend/utils/adt/rangetypes_typanalyze.c
index a18196d8a3..36e885af2d 100644
--- a/src/backend/utils/adt/rangetypes_typanalyze.c
+++ b/src/backend/utils/adt/rangetypes_typanalyze.c
@@ -397,7 +397,7 @@ compute_range_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc,
 		stats->numvalues[slot_idx] = num_hist;
 		stats->statypid[slot_idx] = FLOAT8OID;
 		stats->statyplen[slot_idx] = sizeof(float8);
-		stats->statypbyval[slot_idx] = FLOAT8PASSBYVAL;
+		stats->statypbyval[slot_idx] = true;
 		stats->statypalign[slot_idx] = 'd';
 
 		/* Store the fraction of empty ranges */
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 782291d999..5543440a33 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -1788,41 +1788,6 @@ OidSendFunctionCall(Oid functionId, Datum val)
 }
 
 
-/*-------------------------------------------------------------------------
- *		Support routines for standard maybe-pass-by-reference datatypes
- *
- * int8 and float8 can be passed by value if Datum is wide enough.
- * (For backwards-compatibility reasons, we allow pass-by-ref to be chosen
- * at compile time even if pass-by-val is possible.)
- *
- * Note: there is only one switch controlling the pass-by-value option for
- * both int8 and float8; this is to avoid making things unduly complicated
- * for the timestamp types, which might have either representation.
- *-------------------------------------------------------------------------
- */
-
-#ifndef USE_FLOAT8_BYVAL		/* controls int8 too */
-
-Datum
-Int64GetDatum(int64 X)
-{
-	int64	   *retval = (int64 *) palloc(sizeof(int64));
-
-	*retval = X;
-	return PointerGetDatum(retval);
-}
-
-Datum
-Float8GetDatum(float8 X)
-{
-	float8	   *retval = (float8 *) palloc(sizeof(float8));
-
-	*retval = X;
-	return PointerGetDatum(retval);
-}
-#endif							/* USE_FLOAT8_BYVAL */
-
-
 /*-------------------------------------------------------------------------
  *		Support routines for toastable datatypes
  *-------------------------------------------------------------------------
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 62bbd08d9f..92fe2f531f 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -1580,9 +1580,6 @@ bootstrap_template1(void)
 	bki_lines = replace_token(bki_lines, "ALIGNOF_POINTER",
 							  (sizeof(Pointer) == 4) ? "i" : "d");
 
-	bki_lines = replace_token(bki_lines, "FLOAT8PASSBYVAL",
-							  FLOAT8PASSBYVAL ? "true" : "false");
-
 	bki_lines = replace_token(bki_lines, "POSTGRES",
 							  escape_quotes_bki(username));
 
diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c
index e876f35f38..7a4e4eb957 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -719,7 +719,7 @@ GuessControlValues(void)
 	ControlFile.indexMaxKeys = INDEX_MAX_KEYS;
 	ControlFile.toast_max_chunk_size = TOAST_MAX_CHUNK_SIZE;
 	ControlFile.loblksize = LOBLKSIZE;
-	ControlFile.float8ByVal = FLOAT8PASSBYVAL;
+	ControlFile.float8ByVal = true; /* vestigial */
 
 	/*
 	 * XXX eventually, should try to grovel through old XLOG to develop more
diff --git a/src/include/c.h b/src/include/c.h
index bbdaa88c63..39022f8a9d 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -609,11 +609,11 @@ typedef signed int Offset;
 typedef float float4;
 typedef double float8;
 
-#ifdef USE_FLOAT8_BYVAL
+/*
+ * float8, int8, and related datatypes are now always pass-by-value.
+ * We keep this symbol to avoid breaking extension code that may use it.
+ */
 #define FLOAT8PASSBYVAL true
-#else
-#define FLOAT8PASSBYVAL false
-#endif
 
 /*
  * Oid, RegProcedure, TransactionId, SubTransactionId, MultiXactId,
diff --git a/src/include/catalog/pg_type.dat b/src/include/catalog/pg_type.dat
index 29e4ffffc9..cb730aeac8 100644
--- a/src/include/catalog/pg_type.dat
+++ b/src/include/catalog/pg_type.dat
@@ -54,7 +54,7 @@
   typcollation => 'C' },
 { oid => '20', array_type_oid => '1016',
   descr => '~18 digit integer, 8-byte storage',
-  typname => 'int8', typlen => '8', typbyval => 'FLOAT8PASSBYVAL',
+  typname => 'int8', typlen => '8', typbyval => 't',
   typcategory => 'N', typinput => 'int8in', typoutput => 'int8out',
   typreceive => 'int8recv', typsend => 'int8send', typalign => 'd' },
 { oid => '21', array_type_oid => '1005',
@@ -172,7 +172,7 @@
   typoutput => 'pg_ddl_command_out', typreceive => 'pg_ddl_command_recv',
   typsend => 'pg_ddl_command_send', typalign => 'ALIGNOF_POINTER' },
 { oid => '5069', array_type_oid => '271', descr => 'full transaction id',
-  typname => 'xid8', typlen => '8', typbyval => 'FLOAT8PASSBYVAL',
+  typname => 'xid8', typlen => '8', typbyval => 't',
   typcategory => 'U', typinput => 'xid8in', typoutput => 'xid8out',
   typreceive => 'xid8recv', typsend => 'xid8send', typalign => 'd' },
 
@@ -222,7 +222,7 @@
   typsend => 'float4send', typalign => 'i' },
 { oid => '701', array_type_oid => '1022',
   descr => 'double-precision floating point number, 8-byte storage',
-  typname => 'float8', typlen => '8', typbyval => 'FLOAT8PASSBYVAL',
+  typname => 'float8', typlen => '8', typbyval => 't',
   typcategory => 'N', typispreferred => 't', typinput => 'float8in',
   typoutput => 'float8out', typreceive => 'float8recv', typsend => 'float8send',
   typalign => 'd' },
@@ -237,7 +237,7 @@
   typreceive => 'circle_recv', typsend => 'circle_send', typalign => 'd' },
 { oid => '790', array_type_oid => '791',
   descr => 'monetary amounts, $d,ddd.cc',
-  typname => 'money', typlen => '8', typbyval => 'FLOAT8PASSBYVAL',
+  typname => 'money', typlen => '8', typbyval => 't',
   typcategory => 'N', typinput => 'cash_in', typoutput => 'cash_out',
   typreceive => 'cash_recv', typsend => 'cash_send', typalign => 'd' },
 
@@ -290,7 +290,7 @@
   typinput => 'date_in', typoutput => 'date_out', typreceive => 'date_recv',
   typsend => 'date_send', typalign => 'i' },
 { oid => '1083', array_type_oid => '1183', descr => 'time of day',
-  typname => 'time', typlen => '8', typbyval => 'FLOAT8PASSBYVAL',
+  typname => 'time', typlen => '8', typbyval => 't',
   typcategory => 'D', typinput => 'time_in', typoutput => 'time_out',
   typreceive => 'time_recv', typsend => 'time_send', typmodin => 'timetypmodin',
   typmodout => 'timetypmodout', typalign => 'd' },
@@ -298,14 +298,14 @@
 # OIDS 1100 - 1199
 
 { oid => '1114', array_type_oid => '1115', descr => 'date and time',
-  typname => 'timestamp', typlen => '8', typbyval => 'FLOAT8PASSBYVAL',
+  typname => 'timestamp', typlen => '8', typbyval => 't',
   typcategory => 'D', typinput => 'timestamp_in', typoutput => 'timestamp_out',
   typreceive => 'timestamp_recv', typsend => 'timestamp_send',
   typmodin => 'timestamptypmodin', typmodout => 'timestamptypmodout',
   typalign => 'd' },
 { oid => '1184', array_type_oid => '1185',
   descr => 'date and time with time zone',
-  typname => 'timestamptz', typlen => '8', typbyval => 'FLOAT8PASSBYVAL',
+  typname => 'timestamptz', typlen => '8', typbyval => 't',
   typcategory => 'D', typispreferred => 't', typinput => 'timestamptz_in',
   typoutput => 'timestamptz_out', typreceive => 'timestamptz_recv',
   typsend => 'timestamptz_send', typmodin => 'timestamptztypmodin',
@@ -413,7 +413,7 @@
 
 # pg_lsn
 { oid => '3220', array_type_oid => '3221', descr => 'PostgreSQL LSN',
-  typname => 'pg_lsn', typlen => '8', typbyval => 'FLOAT8PASSBYVAL',
+  typname => 'pg_lsn', typlen => '8', typbyval => 't',
   typcategory => 'U', typinput => 'pg_lsn_in', typoutput => 'pg_lsn_out',
   typreceive => 'pg_lsn_recv', typsend => 'pg_lsn_send', typalign => 'd' },
 
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index 0fe7b4ebc7..c7236e4297 100644
--- a/src/include/fmgr.h
+++ b/src/include/fmgr.h
@@ -469,7 +469,7 @@ typedef struct
 	int			funcmaxargs;	/* FUNC_MAX_ARGS */
 	int			indexmaxkeys;	/* INDEX_MAX_KEYS */
 	int			namedatalen;	/* NAMEDATALEN */
-	int			float8byval;	/* FLOAT8PASSBYVAL */
+	int			float8byval;	/* FLOAT8PASSBYVAL (now vestigial) */
 	char		abi_extra[32];	/* see pg_config_manual.h */
 } Pg_abi_values;
 
diff --git a/src/include/postgres.h b/src/include/postgres.h
index e81829bfa6..357cbd6fd9 100644
--- a/src/include/postgres.h
+++ b/src/include/postgres.h
@@ -388,68 +388,41 @@ NameGetDatum(const NameData *X)
 /*
  * DatumGetInt64
  *		Returns 64-bit integer value of a datum.
- *
- * Note: this function hides whether int64 is pass by value or by reference.
  */
 static inline int64
 DatumGetInt64(Datum X)
 {
-#ifdef USE_FLOAT8_BYVAL
 	return (int64) X;
-#else
-	return *((int64 *) DatumGetPointer(X));
-#endif
 }
 
 /*
  * Int64GetDatum
  *		Returns datum representation for a 64-bit integer.
- *
- * Note: if int64 is pass by reference, this function returns a reference
- * to palloc'd space.
  */
-#ifdef USE_FLOAT8_BYVAL
 static inline Datum
 Int64GetDatum(int64 X)
 {
 	return (Datum) X;
 }
-#else
-extern Datum Int64GetDatum(int64 X);
-#endif
-
 
 /*
  * DatumGetUInt64
  *		Returns 64-bit unsigned integer value of a datum.
- *
- * Note: this function hides whether int64 is pass by value or by reference.
  */
 static inline uint64
 DatumGetUInt64(Datum X)
 {
-#ifdef USE_FLOAT8_BYVAL
 	return (uint64) X;
-#else
-	return *((uint64 *) DatumGetPointer(X));
-#endif
 }
 
 /*
  * UInt64GetDatum
  *		Returns datum representation for a 64-bit unsigned integer.
- *
- * Note: if int64 is pass by reference, this function returns a reference
- * to palloc'd space.
  */
 static inline Datum
 UInt64GetDatum(uint64 X)
 {
-#ifdef USE_FLOAT8_BYVAL
 	return (Datum) X;
-#else
-	return Int64GetDatum((int64) X);
-#endif
 }
 
 /*
@@ -497,13 +470,10 @@ Float4GetDatum(float4 X)
 /*
  * DatumGetFloat8
  *		Returns 8-byte floating point value of a datum.
- *
- * Note: this function hides whether float8 is pass by value or by reference.
  */
 static inline float8
 DatumGetFloat8(Datum X)
 {
-#ifdef USE_FLOAT8_BYVAL
 	union
 	{
 		int64		value;
@@ -512,19 +482,12 @@ DatumGetFloat8(Datum X)
 
 	myunion.value = DatumGetInt64(X);
 	return myunion.retval;
-#else
-	return *((float8 *) DatumGetPointer(X));
-#endif
 }
 
 /*
  * Float8GetDatum
  *		Returns datum representation for an 8-byte floating point number.
- *
- * Note: if float8 is pass by reference, this function returns a reference
- * to palloc'd space.
  */
-#ifdef USE_FLOAT8_BYVAL
 static inline Datum
 Float8GetDatum(float8 X)
 {
@@ -537,35 +500,22 @@ Float8GetDatum(float8 X)
 	myunion.value = X;
 	return Int64GetDatum(myunion.retval);
 }
-#else
-extern Datum Float8GetDatum(float8 X);
-#endif
-
 
 /*
  * Int64GetDatumFast
  * Float8GetDatumFast
  *
- * These macros are intended to allow writing code that does not depend on
+ * These macros were intended to allow writing code that does not depend on
  * whether int64 and float8 are pass-by-reference types, while not
- * sacrificing performance when they are.  The argument must be a variable
- * that will exist and have the same value for as long as the Datum is needed.
- * In the pass-by-ref case, the address of the variable is taken to use as
- * the Datum.  In the pass-by-val case, these are the same as the non-Fast
- * functions, except for asserting that the variable is of the correct type.
+ * sacrificing performance when they are.  They are no longer different
+ * from the regular functions, though we keep the assertions to protect
+ * code that might get back-patched into older branches.
  */
 
-#ifdef USE_FLOAT8_BYVAL
 #define Int64GetDatumFast(X) \
 	(AssertVariableIsOfTypeMacro(X, int64), Int64GetDatum(X))
 #define Float8GetDatumFast(X) \
 	(AssertVariableIsOfTypeMacro(X, double), Float8GetDatum(X))
-#else
-#define Int64GetDatumFast(X) \
-	(AssertVariableIsOfTypeMacro(X, int64), PointerGetDatum(&(X)))
-#define Float8GetDatumFast(X) \
-	(AssertVariableIsOfTypeMacro(X, double), PointerGetDatum(&(X)))
-#endif
 
 
 /* ----------------------------------------------------------------
-- 
2.39.5

