From 279228b69df4334cd44c0dbb1ba31b6d0bbc078e Mon Sep 17 00:00:00 2001
From: Corey Huinker <corey.huinker@gmail.com>
Date: Sun, 28 Jun 2026 16:09:49 -0500
Subject: [PATCH v1 2/5] Make internal statistics_update functions stop using
 fcinfo.

Change the function signature of relation_statistics_update_internal,
attribute_statistics_update_internal, and extended_staistics_update to
use a NullableDatum array instead of a full FunctionCallInfo.
---
 src/backend/statistics/attribute_stats.c      | 73 +++++++++----------
 src/backend/statistics/extended_stats_funcs.c | 62 ++++++++--------
 src/backend/statistics/relation_stats.c       | 24 +++---
 3 files changed, 79 insertions(+), 80 deletions(-)

diff --git a/src/backend/statistics/attribute_stats.c b/src/backend/statistics/attribute_stats.c
index 11bc1df1e0c..a50d60223c9 100644
--- a/src/backend/statistics/attribute_stats.c
+++ b/src/backend/statistics/attribute_stats.c
@@ -109,7 +109,7 @@ static bool attribute_statistics_update_internal(Oid reloid,
 												 const char *attname,
 												 AttrNumber attnum,
 												 bool inherited,
-												 FunctionCallInfo fcinfo);
+												 const NullableDatum *args);
 static void upsert_pg_statistic(Relation starel, HeapTuple oldtup,
 								const Datum *values, const bool *nulls, const bool *replaces);
 static bool delete_pg_statistic(Oid reloid, AttrNumber attnum, bool stainherit);
@@ -205,7 +205,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo)
 	inherited = PG_GETARG_BOOL(INHERITED_ARG);
 
 	return attribute_statistics_update_internal(reloid, attname, attnum,
-												inherited, fcinfo);
+												inherited, fcinfo->args);
 }
 
 /*
@@ -214,7 +214,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo)
 static bool
 attribute_statistics_update_internal(Oid reloid,
 									 const char *attname, AttrNumber attnum,
-									 bool inherited, FunctionCallInfo fcinfo)
+									 bool inherited, const NullableDatum *args)
 {
 	Relation	starel;
 	HeapTuple	statup;
@@ -231,16 +231,16 @@ attribute_statistics_update_internal(Oid reloid,
 
 	FmgrInfo	array_in_fn;
 
-	bool		do_mcv = !PG_ARGISNULL(MOST_COMMON_FREQS_ARG) &&
-		!PG_ARGISNULL(MOST_COMMON_VALS_ARG);
-	bool		do_histogram = !PG_ARGISNULL(HISTOGRAM_BOUNDS_ARG);
-	bool		do_correlation = !PG_ARGISNULL(CORRELATION_ARG);
-	bool		do_mcelem = !PG_ARGISNULL(MOST_COMMON_ELEMS_ARG) &&
-		!PG_ARGISNULL(MOST_COMMON_ELEM_FREQS_ARG);
-	bool		do_dechist = !PG_ARGISNULL(ELEM_COUNT_HISTOGRAM_ARG);
-	bool		do_bounds_histogram = !PG_ARGISNULL(RANGE_BOUNDS_HISTOGRAM_ARG);
-	bool		do_range_length_histogram = !PG_ARGISNULL(RANGE_LENGTH_HISTOGRAM_ARG) &&
-		!PG_ARGISNULL(RANGE_EMPTY_FRAC_ARG);
+	bool		do_mcv = !args[MOST_COMMON_FREQS_ARG].isnull &&
+		!args[MOST_COMMON_VALS_ARG].isnull;
+	bool		do_histogram = !args[HISTOGRAM_BOUNDS_ARG].isnull;
+	bool		do_correlation = !args[CORRELATION_ARG].isnull;
+	bool		do_mcelem = !args[MOST_COMMON_ELEMS_ARG].isnull &&
+		!args[MOST_COMMON_ELEM_FREQS_ARG].isnull;
+	bool		do_dechist = !args[ELEM_COUNT_HISTOGRAM_ARG].isnull;
+	bool		do_bounds_histogram = !args[RANGE_BOUNDS_HISTOGRAM_ARG].isnull;
+	bool		do_range_length_histogram = !args[RANGE_LENGTH_HISTOGRAM_ARG].isnull &&
+		!args[RANGE_EMPTY_FRAC_ARG].isnull;
 
 	Datum		values[Natts_pg_statistic] = {0};
 	bool		nulls[Natts_pg_statistic] = {0};
@@ -250,34 +250,33 @@ attribute_statistics_update_internal(Oid reloid,
 
 	/*
 	 * Check argument sanity. If some arguments are unusable, emit a WARNING
-	 * and set the corresponding argument to NULL in fcinfo.
 	 */
 
-	if (!stats_check_arg_array(fcinfo->args, attarginfo, MOST_COMMON_FREQS_ARG))
+	if (!stats_check_arg_array(args, attarginfo, MOST_COMMON_FREQS_ARG))
 	{
 		do_mcv = false;
 		result = false;
 	}
 
-	if (!stats_check_arg_array(fcinfo->args, attarginfo, MOST_COMMON_ELEM_FREQS_ARG))
+	if (!stats_check_arg_array(args, attarginfo, MOST_COMMON_ELEM_FREQS_ARG))
 	{
 		do_mcelem = false;
 		result = false;
 	}
-	if (!stats_check_arg_array(fcinfo->args, attarginfo, ELEM_COUNT_HISTOGRAM_ARG))
+	if (!stats_check_arg_array(args, attarginfo, ELEM_COUNT_HISTOGRAM_ARG))
 	{
 		do_dechist = false;
 		result = false;
 	}
 
-	if (!stats_check_arg_pair(fcinfo->args, attarginfo,
+	if (!stats_check_arg_pair(args, attarginfo,
 							  MOST_COMMON_VALS_ARG, MOST_COMMON_FREQS_ARG))
 	{
 		do_mcv = false;
 		result = false;
 	}
 
-	if (!stats_check_arg_pair(fcinfo->args, attarginfo,
+	if (!stats_check_arg_pair(args, attarginfo,
 							  MOST_COMMON_ELEMS_ARG,
 							  MOST_COMMON_ELEM_FREQS_ARG))
 	{
@@ -285,7 +284,7 @@ attribute_statistics_update_internal(Oid reloid,
 		result = false;
 	}
 
-	if (!stats_check_arg_pair(fcinfo->args, attarginfo,
+	if (!stats_check_arg_pair(args, attarginfo,
 							  RANGE_LENGTH_HISTOGRAM_ARG,
 							  RANGE_EMPTY_FRAC_ARG))
 	{
@@ -361,19 +360,19 @@ attribute_statistics_update_internal(Oid reloid,
 								 replaces);
 
 	/* if specified, set to argument values */
-	if (!PG_ARGISNULL(NULL_FRAC_ARG))
+	if (!args[NULL_FRAC_ARG].isnull)
 	{
-		values[Anum_pg_statistic_stanullfrac - 1] = PG_GETARG_DATUM(NULL_FRAC_ARG);
+		values[Anum_pg_statistic_stanullfrac - 1] = args[NULL_FRAC_ARG].value;
 		replaces[Anum_pg_statistic_stanullfrac - 1] = true;
 	}
-	if (!PG_ARGISNULL(AVG_WIDTH_ARG))
+	if (!args[AVG_WIDTH_ARG].isnull)
 	{
-		values[Anum_pg_statistic_stawidth - 1] = PG_GETARG_DATUM(AVG_WIDTH_ARG);
+		values[Anum_pg_statistic_stawidth - 1] = args[AVG_WIDTH_ARG].value;
 		replaces[Anum_pg_statistic_stawidth - 1] = true;
 	}
-	if (!PG_ARGISNULL(N_DISTINCT_ARG))
+	if (!args[N_DISTINCT_ARG].isnull)
 	{
-		values[Anum_pg_statistic_stadistinct - 1] = PG_GETARG_DATUM(N_DISTINCT_ARG);
+		values[Anum_pg_statistic_stadistinct - 1] = args[N_DISTINCT_ARG].value;
 		replaces[Anum_pg_statistic_stadistinct - 1] = true;
 	}
 
@@ -381,10 +380,10 @@ attribute_statistics_update_internal(Oid reloid,
 	if (do_mcv)
 	{
 		bool		converted;
-		Datum		stanumbers = PG_GETARG_DATUM(MOST_COMMON_FREQS_ARG);
+		Datum		stanumbers = args[MOST_COMMON_FREQS_ARG].value;
 		Datum		stavalues = statatt_build_stavalues("most_common_vals",
 														&array_in_fn,
-														PG_GETARG_DATUM(MOST_COMMON_VALS_ARG),
+														args[MOST_COMMON_VALS_ARG].value,
 														atttypid, atttypmod,
 														&converted);
 
@@ -424,7 +423,7 @@ attribute_statistics_update_internal(Oid reloid,
 
 		stavalues = statatt_build_stavalues("histogram_bounds",
 											&array_in_fn,
-											PG_GETARG_DATUM(HISTOGRAM_BOUNDS_ARG),
+											args[HISTOGRAM_BOUNDS_ARG].value,
 											atttypid, atttypmod,
 											&converted);
 
@@ -442,7 +441,7 @@ attribute_statistics_update_internal(Oid reloid,
 	/* STATISTIC_KIND_CORRELATION */
 	if (do_correlation)
 	{
-		Datum		elems[] = {PG_GETARG_DATUM(CORRELATION_ARG)};
+		Datum		elems[] = {args[CORRELATION_ARG].value};
 		ArrayType  *arry = construct_array_builtin(elems, 1, FLOAT4OID);
 		Datum		stanumbers = PointerGetDatum(arry);
 
@@ -455,13 +454,13 @@ attribute_statistics_update_internal(Oid reloid,
 	/* STATISTIC_KIND_MCELEM */
 	if (do_mcelem)
 	{
-		Datum		stanumbers = PG_GETARG_DATUM(MOST_COMMON_ELEM_FREQS_ARG);
+		Datum		stanumbers = args[MOST_COMMON_ELEM_FREQS_ARG].value;
 		bool		converted = false;
 		Datum		stavalues;
 
 		stavalues = statatt_build_stavalues("most_common_elems",
 											&array_in_fn,
-											PG_GETARG_DATUM(MOST_COMMON_ELEMS_ARG),
+											args[MOST_COMMON_ELEMS_ARG].value,
 											elemtypid, atttypmod,
 											&converted);
 
@@ -479,7 +478,7 @@ attribute_statistics_update_internal(Oid reloid,
 	/* STATISTIC_KIND_DECHIST */
 	if (do_dechist)
 	{
-		Datum		stanumbers = PG_GETARG_DATUM(ELEM_COUNT_HISTOGRAM_ARG);
+		Datum		stanumbers = args[ELEM_COUNT_HISTOGRAM_ARG].value;
 
 		statatt_set_slot(values, nulls, replaces,
 						 STATISTIC_KIND_DECHIST,
@@ -509,7 +508,7 @@ attribute_statistics_update_internal(Oid reloid,
 
 		stavalues = statatt_build_stavalues("range_bounds_histogram",
 											&array_in_fn,
-											PG_GETARG_DATUM(RANGE_BOUNDS_HISTOGRAM_ARG),
+											args[RANGE_BOUNDS_HISTOGRAM_ARG].value,
 											bounds_typid, atttypmod,
 											&converted);
 
@@ -529,7 +528,7 @@ attribute_statistics_update_internal(Oid reloid,
 	if (do_range_length_histogram)
 	{
 		/* The anyarray is always a float8[] for this stakind */
-		Datum		elems[] = {PG_GETARG_DATUM(RANGE_EMPTY_FRAC_ARG)};
+		Datum		elems[] = {args[RANGE_EMPTY_FRAC_ARG].value};
 		ArrayType  *arry = construct_array_builtin(elems, 1, FLOAT4OID);
 		Datum		stanumbers = PointerGetDatum(arry);
 
@@ -538,7 +537,7 @@ attribute_statistics_update_internal(Oid reloid,
 
 		stavalues = statatt_build_stavalues("range_length_histogram",
 											&array_in_fn,
-											PG_GETARG_DATUM(RANGE_LENGTH_HISTOGRAM_ARG),
+											args[RANGE_LENGTH_HISTOGRAM_ARG].value,
 											FLOAT8OID, 0, &converted);
 
 		if (converted)
@@ -796,7 +795,7 @@ import_attribute_statistics(Relation rel, AttrNumber attnum, bool inherited,
 	newfcinfo->args[RANGE_BOUNDS_HISTOGRAM_ARG] = *range_bounds_histogram;
 
 	return attribute_statistics_update_internal(reloid, attname, attnum,
-												inherited, newfcinfo);
+												inherited, newfcinfo->args);
 }
 
 /*
diff --git a/src/backend/statistics/extended_stats_funcs.c b/src/backend/statistics/extended_stats_funcs.c
index 2117617ab18..b479c49c85e 100644
--- a/src/backend/statistics/extended_stats_funcs.c
+++ b/src/backend/statistics/extended_stats_funcs.c
@@ -121,7 +121,7 @@ static const char *extexprargname[NUM_ATTRIBUTE_STATS_ELEMS] =
 	"range_bounds_histogram"
 };
 
-static bool extended_statistics_update(FunctionCallInfo fcinfo);
+static bool extended_statistics_update(const NullableDatum *args);
 
 static HeapTuple get_pg_statistic_ext(Relation pg_stext, Oid nspoid,
 									  const char *stxname);
@@ -311,7 +311,7 @@ upsert_pg_statistic_ext_data(const Datum *values, const bool *nulls,
  * be updated.
  */
 static bool
-extended_statistics_update(FunctionCallInfo fcinfo)
+extended_statistics_update(const NullableDatum *args)
 {
 	char	   *relnspname;
 	char	   *relname;
@@ -356,12 +356,12 @@ extended_statistics_update(FunctionCallInfo fcinfo)
 	 * Therefore, none of the three array values is meaningful unless the
 	 * other two are also present and in sync in terms of array length.
 	 */
-	has.mcv = (!PG_ARGISNULL(MOST_COMMON_VALS_ARG) &&
-			   !PG_ARGISNULL(MOST_COMMON_FREQS_ARG) &&
-			   !PG_ARGISNULL(MOST_COMMON_BASE_FREQS_ARG));
-	has.ndistinct = !PG_ARGISNULL(NDISTINCT_ARG);
-	has.dependencies = !PG_ARGISNULL(DEPENDENCIES_ARG);
-	has.expressions = !PG_ARGISNULL(EXPRESSIONS_ARG);
+	has.mcv = (!args[MOST_COMMON_VALS_ARG].isnull &&
+			   !args[MOST_COMMON_FREQS_ARG].isnull &&
+			   !args[MOST_COMMON_BASE_FREQS_ARG].isnull);
+	has.ndistinct = !args[NDISTINCT_ARG].isnull;
+	has.dependencies = !args[DEPENDENCIES_ARG].isnull;
+	has.expressions = !args[EXPRESSIONS_ARG].isnull;
 
 	if (RecoveryInProgress())
 	{
@@ -373,18 +373,18 @@ extended_statistics_update(FunctionCallInfo fcinfo)
 	}
 
 	/* relation arguments */
-	stats_check_required_arg(fcinfo->args, extarginfo, RELSCHEMA_ARG);
-	relnspname = TextDatumGetCString(PG_GETARG_DATUM(RELSCHEMA_ARG));
-	stats_check_required_arg(fcinfo->args, extarginfo, RELNAME_ARG);
-	relname = TextDatumGetCString(PG_GETARG_DATUM(RELNAME_ARG));
+	stats_check_required_arg(args, extarginfo, RELSCHEMA_ARG);
+	relnspname = TextDatumGetCString(args[RELSCHEMA_ARG].value);
+	stats_check_required_arg(args, extarginfo, RELNAME_ARG);
+	relname = TextDatumGetCString(args[RELNAME_ARG].value);
 
 	/* extended statistics arguments */
-	stats_check_required_arg(fcinfo->args, extarginfo, STATSCHEMA_ARG);
-	nspname = TextDatumGetCString(PG_GETARG_DATUM(STATSCHEMA_ARG));
-	stats_check_required_arg(fcinfo->args, extarginfo, STATNAME_ARG);
-	stxname = TextDatumGetCString(PG_GETARG_DATUM(STATNAME_ARG));
-	stats_check_required_arg(fcinfo->args, extarginfo, INHERITED_ARG);
-	inherited = PG_GETARG_BOOL(INHERITED_ARG);
+	stats_check_required_arg(args, extarginfo, STATSCHEMA_ARG);
+	nspname = TextDatumGetCString(args[STATSCHEMA_ARG].value);
+	stats_check_required_arg(args, extarginfo, STATNAME_ARG);
+	stxname = TextDatumGetCString(args[STATNAME_ARG].value);
+	stats_check_required_arg(args, extarginfo, INHERITED_ARG);
+	inherited = DatumGetBool(args[INHERITED_ARG].value);
 
 	/*
 	 * First open the relation where we expect to find the statistics.  This
@@ -514,9 +514,9 @@ extended_statistics_update(FunctionCallInfo fcinfo)
 	 */
 	if (!enabled.mcv)
 	{
-		if (!PG_ARGISNULL(MOST_COMMON_VALS_ARG) ||
-			!PG_ARGISNULL(MOST_COMMON_FREQS_ARG) ||
-			!PG_ARGISNULL(MOST_COMMON_BASE_FREQS_ARG))
+		if (!args[MOST_COMMON_VALS_ARG].isnull ||
+			!args[MOST_COMMON_FREQS_ARG].isnull ||
+			!args[MOST_COMMON_BASE_FREQS_ARG].isnull)
 		{
 			ereport(WARNING,
 					errcode(ERRCODE_INVALID_PARAMETER_VALUE),
@@ -538,9 +538,9 @@ extended_statistics_update(FunctionCallInfo fcinfo)
 		 * statistics object expects something, something is wrong.  This
 		 * issues a WARNING if a partial input has been provided.
 		 */
-		if (!PG_ARGISNULL(MOST_COMMON_VALS_ARG) ||
-			!PG_ARGISNULL(MOST_COMMON_FREQS_ARG) ||
-			!PG_ARGISNULL(MOST_COMMON_BASE_FREQS_ARG))
+		if (!args[MOST_COMMON_VALS_ARG].isnull ||
+			!args[MOST_COMMON_FREQS_ARG].isnull ||
+			!args[MOST_COMMON_BASE_FREQS_ARG].isnull)
 		{
 			ereport(WARNING,
 					errcode(ERRCODE_INVALID_PARAMETER_VALUE),
@@ -655,7 +655,7 @@ extended_statistics_update(FunctionCallInfo fcinfo)
 
 	if (has.ndistinct)
 	{
-		Datum		ndistinct_datum = PG_GETARG_DATUM(NDISTINCT_ARG);
+		Datum		ndistinct_datum = args[NDISTINCT_ARG].value;
 		bytea	   *data = DatumGetByteaPP(ndistinct_datum);
 		MVNDistinct *ndistinct = statext_ndistinct_deserialize(data);
 
@@ -674,7 +674,7 @@ extended_statistics_update(FunctionCallInfo fcinfo)
 
 	if (has.dependencies)
 	{
-		Datum		dependencies_datum = PG_GETARG_DATUM(DEPENDENCIES_ARG);
+		Datum		dependencies_datum = args[DEPENDENCIES_ARG].value;
 		bytea	   *data = DatumGetByteaPP(dependencies_datum);
 		MVDependencies *dependencies = statext_dependencies_deserialize(data);
 
@@ -696,9 +696,9 @@ extended_statistics_update(FunctionCallInfo fcinfo)
 		Datum		datum;
 		bool		val_ok = false;
 
-		datum = import_mcv(PG_GETARG_ARRAYTYPE_P(MOST_COMMON_VALS_ARG),
-						   PG_GETARG_ARRAYTYPE_P(MOST_COMMON_FREQS_ARG),
-						   PG_GETARG_ARRAYTYPE_P(MOST_COMMON_BASE_FREQS_ARG),
+		datum = import_mcv(DatumGetArrayTypeP(args[MOST_COMMON_VALS_ARG].value),
+						   DatumGetArrayTypeP(args[MOST_COMMON_FREQS_ARG].value),
+						   DatumGetArrayTypeP(args[MOST_COMMON_BASE_FREQS_ARG].value),
 						   atttypids, atttypmods, atttypcolls, numattrs,
 						   &val_ok);
 
@@ -733,7 +733,7 @@ extended_statistics_update(FunctionCallInfo fcinfo)
 								   &atttypids[numattnums],
 								   &atttypmods[numattnums],
 								   &atttypcolls[numattnums],
-								   PG_GETARG_JSONB_P(EXPRESSIONS_ARG),
+								   DatumGetJsonbP(args[EXPRESSIONS_ARG].value),
 								   &ok);
 
 		table_close(pgsd, RowExclusiveLock);
@@ -1733,7 +1733,7 @@ pg_restore_extended_stats(PG_FUNCTION_ARGS)
 	if (!stats_fill_fcinfo_from_arg_pairs(fcinfo, positional_fcinfo, extarginfo))
 		result = false;
 
-	if (!extended_statistics_update(positional_fcinfo))
+	if (!extended_statistics_update(positional_fcinfo->args))
 		result = false;
 
 	PG_RETURN_BOOL(result);
diff --git a/src/backend/statistics/relation_stats.c b/src/backend/statistics/relation_stats.c
index faa5c716b1a..6ec3f4d068d 100644
--- a/src/backend/statistics/relation_stats.c
+++ b/src/backend/statistics/relation_stats.c
@@ -61,7 +61,7 @@ static struct StatsArgInfo relarginfo[] =
 
 static bool relation_statistics_update(FunctionCallInfo fcinfo);
 static bool relation_statistics_update_internal(Oid reloid,
-												FunctionCallInfo fcinfo);
+												const NullableDatum *args);
 
 /*
  * Internal function for modifying statistics for a relation.
@@ -90,14 +90,14 @@ relation_statistics_update(FunctionCallInfo fcinfo)
 									  ShareUpdateExclusiveLock, 0,
 									  RangeVarCallbackForStats, &locked_table);
 
-	return relation_statistics_update_internal(reloid, fcinfo);
+	return relation_statistics_update_internal(reloid, fcinfo->args);
 }
 
 /*
  * Workhorse function for relation_statistics_update.
  */
 static bool
-relation_statistics_update_internal(Oid reloid, FunctionCallInfo fcinfo)
+relation_statistics_update_internal(Oid reloid, const NullableDatum *args)
 {
 	int32		relpages = 0;
 	bool		update_relpages = false;
@@ -116,15 +116,15 @@ relation_statistics_update_internal(Oid reloid, FunctionCallInfo fcinfo)
 	int			nreplaces = 0;
 	bool		result = true;
 
-	if (!PG_ARGISNULL(RELPAGES_ARG))
+	if (!args[RELPAGES_ARG].isnull)
 	{
-		relpages = PG_GETARG_INT32(RELPAGES_ARG);
+		relpages = DatumGetInt32(args[RELPAGES_ARG].value);
 		update_relpages = true;
 	}
 
-	if (!PG_ARGISNULL(RELTUPLES_ARG))
+	if (!args[RELTUPLES_ARG].isnull)
 	{
-		reltuples = PG_GETARG_FLOAT4(RELTUPLES_ARG);
+		reltuples = DatumGetFloat4(args[RELTUPLES_ARG].value);
 		if (isnan(reltuples) || isinf(reltuples))
 		{
 			ereport(WARNING,
@@ -143,15 +143,15 @@ relation_statistics_update_internal(Oid reloid, FunctionCallInfo fcinfo)
 			update_reltuples = true;
 	}
 
-	if (!PG_ARGISNULL(RELALLVISIBLE_ARG))
+	if (!args[RELALLVISIBLE_ARG].isnull)
 	{
-		relallvisible = PG_GETARG_INT32(RELALLVISIBLE_ARG);
+		relallvisible = DatumGetInt32(args[RELALLVISIBLE_ARG].value);
 		update_relallvisible = true;
 	}
 
-	if (!PG_ARGISNULL(RELALLFROZEN_ARG))
+	if (!args[RELALLFROZEN_ARG].isnull)
 	{
-		relallfrozen = PG_GETARG_INT32(RELALLFROZEN_ARG);
+		relallfrozen = DatumGetInt32(args[RELALLFROZEN_ARG].value);
 		update_relallfrozen = true;
 	}
 
@@ -302,5 +302,5 @@ import_relation_statistics(Relation rel,
 	newfcinfo->args[RELALLFROZEN_ARG] = *relallfrozen;
 
 	return relation_statistics_update_internal(RelationGetRelid(rel),
-											   newfcinfo);
+											   newfcinfo->args);
 }
-- 
2.50.1 (Apple Git-155)

