From 043fe55dde07e12c0c21aab5b3d5f4fc412d2b38 Mon Sep 17 00:00:00 2001 From: Corey Huinker Date: Mon, 3 Aug 2026 02:13:14 -0400 Subject: [PATCH v3 11/15] Swtich internal statistics update functions to using named parameters. This modifies the pattern of the the *_statistics_update_internal() functions to stop using arrays of NullableDatum in favor of using multiple NullableDatum parameters. This makes the code more maintainable in that we do not need to have two arrays of StatsArgInfo, one with all of the parameters from the SQL function and another more abbreviated list used by the internal import_* function, as the index names would likely be very similar between the two sets thus making subtle bugs more likely. Additionally, any new stats automatically mean new parameters to the *update_internal() functions, whereas an array parameter would not detect that the caller didn't provide a big-enough array. --- src/backend/statistics/attribute_stats.c | 171 ++++++++++-------- src/backend/statistics/extended_stats_funcs.c | 5 + src/backend/statistics/relation_stats.c | 136 +++++++------- 3 files changed, 174 insertions(+), 138 deletions(-) diff --git a/src/backend/statistics/attribute_stats.c b/src/backend/statistics/attribute_stats.c index d053d91e5dc..08d294607ac 100644 --- a/src/backend/statistics/attribute_stats.c +++ b/src/backend/statistics/attribute_stats.c @@ -39,10 +39,10 @@ enum attribute_stats_argnum { ATTARG_ATTRELSCHEMA = 0, ATTARG_ATTRELNAME, - ATTARG_VERSION, ATTARG_ATTNAME, ATTARG_ATTNUM, ATTARG_INHERITED, + ATTARG_VERSION, ATTARG_NULL_FRAC, ATTARG_AVG_WIDTH, ATTARG_N_DISTINCT, @@ -63,10 +63,10 @@ static struct StatsArgInfo attarginfo[] = { [ATTARG_ATTRELSCHEMA] = {"schemaname", TEXTOID}, [ATTARG_ATTRELNAME] = {"relname", TEXTOID}, - [ATTARG_VERSION] = {"version", INT4OID}, [ATTARG_ATTNAME] = {"attname", TEXTOID}, [ATTARG_ATTNUM] = {"attnum", INT2OID}, [ATTARG_INHERITED] = {"inherited", BOOLOID}, + [ATTARG_VERSION] = {"version", INT4OID}, [ATTARG_NULL_FRAC] = {"null_frac", FLOAT4OID}, [ATTARG_AVG_WIDTH] = {"avg_width", INT4OID}, [ATTARG_N_DISTINCT] = {"n_distinct", FLOAT4OID}, @@ -111,7 +111,20 @@ static bool attribute_statistics_update_internal(Oid reloid, const char *attname, AttrNumber attnum, bool inherited, - const NullableDatum *args); + const NullableDatum *version, + const NullableDatum *null_frac, + const NullableDatum *avg_width, + const NullableDatum *n_distinct, + const NullableDatum *most_common_vals, + const NullableDatum *most_common_freqs, + const NullableDatum *histogram_bounds, + const NullableDatum *correlation, + const NullableDatum *most_common_elems, + const NullableDatum *most_common_elem_freqs, + const NullableDatum *elem_count_histogram, + const NullableDatum *range_length_histogram, + const NullableDatum *range_empty_frac, + const NullableDatum *range_bounds_histogram); 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); @@ -207,7 +220,22 @@ attribute_statistics_update(const NullableDatum *args) inherited = DatumGetBool(args[ATTARG_INHERITED].value); return attribute_statistics_update_internal(reloid, attname, attnum, - inherited, args); + inherited, + &args[ATTARG_VERSION], + &args[ATTARG_NULL_FRAC], + &args[ATTARG_AVG_WIDTH], + &args[ATTARG_N_DISTINCT], + &args[ATTARG_MOST_COMMON_VALS], + &args[ATTARG_MOST_COMMON_FREQS], + &args[ATTARG_HISTOGRAM_BOUNDS], + &args[ATTARG_CORRELATION], + &args[ATTARG_MOST_COMMON_ELEMS], + &args[ATTARG_MOST_COMMON_ELEM_FREQS], + &args[ATTARG_ELEM_COUNT_HISTOGRAM], + &args[ATTARG_RANGE_LENGTH_HISTOGRAM], + &args[ATTARG_RANGE_EMPTY_FRAC], + &args[ATTARG_RANGE_BOUNDS_HISTOGRAM] + ); } /* @@ -216,7 +244,21 @@ attribute_statistics_update(const NullableDatum *args) static bool attribute_statistics_update_internal(Oid reloid, const char *attname, AttrNumber attnum, - bool inherited, const NullableDatum *args) + bool inherited, + const NullableDatum *version, + const NullableDatum *null_frac, + const NullableDatum *avg_width, + const NullableDatum *n_distinct, + const NullableDatum *most_common_vals, + const NullableDatum *most_common_freqs, + const NullableDatum *histogram_bounds, + const NullableDatum *correlation, + const NullableDatum *most_common_elems, + const NullableDatum *most_common_elem_freqs, + const NullableDatum *elem_count_histogram, + const NullableDatum *range_length_histogram, + const NullableDatum *range_empty_frac, + const NullableDatum *range_bounds_histogram) { Relation starel; HeapTuple statup; @@ -233,16 +275,16 @@ attribute_statistics_update_internal(Oid reloid, FmgrInfo array_in_fn; - bool do_mcv = !args[ATTARG_MOST_COMMON_FREQS].isnull && - !args[ATTARG_MOST_COMMON_VALS].isnull; - bool do_histogram = !args[ATTARG_HISTOGRAM_BOUNDS].isnull; - bool do_correlation = !args[ATTARG_CORRELATION].isnull; - bool do_mcelem = !args[ATTARG_MOST_COMMON_ELEMS].isnull && - !args[ATTARG_MOST_COMMON_ELEM_FREQS].isnull; - bool do_dechist = !args[ATTARG_ELEM_COUNT_HISTOGRAM].isnull; - bool do_bounds_histogram = !args[ATTARG_RANGE_BOUNDS_HISTOGRAM].isnull; - bool do_range_length_histogram = !args[ATTARG_RANGE_LENGTH_HISTOGRAM].isnull && - !args[ATTARG_RANGE_EMPTY_FRAC].isnull; + bool do_mcv = !most_common_freqs->isnull && + !most_common_vals->isnull; + bool do_histogram = !histogram_bounds->isnull; + bool do_correlation = !correlation->isnull; + bool do_mcelem = !most_common_elems->isnull && + !most_common_elem_freqs->isnull; + bool do_dechist = !elem_count_histogram->isnull; + bool do_bounds_histogram = !range_bounds_histogram->isnull; + bool do_range_length_histogram = !range_length_histogram->isnull && + !range_empty_frac->isnull; Datum values[Natts_pg_statistic] = {0}; bool nulls[Natts_pg_statistic] = {0}; @@ -255,25 +297,27 @@ attribute_statistics_update_internal(Oid reloid, * and set the corresponding argument to NULL in fcinfo. */ - if (!stats_check_arg_array(&args[ATTARG_MOST_COMMON_FREQS], attarginfo[ATTARG_MOST_COMMON_FREQS].argname)) + if (!stats_check_arg_array(most_common_freqs, + attarginfo[ATTARG_MOST_COMMON_FREQS].argname)) { do_mcv = false; result = false; } - if (!stats_check_arg_array(&args[ATTARG_MOST_COMMON_ELEM_FREQS], attarginfo[ATTARG_MOST_COMMON_ELEM_FREQS].argname)) + if (!stats_check_arg_array(most_common_elem_freqs, + attarginfo[ATTARG_MOST_COMMON_ELEM_FREQS].argname)) { do_mcelem = false; result = false; } - if (!stats_check_arg_array(&args[ATTARG_ELEM_COUNT_HISTOGRAM], attarginfo[ATTARG_ELEM_COUNT_HISTOGRAM].argname)) + if (!stats_check_arg_array(elem_count_histogram, + attarginfo[ATTARG_ELEM_COUNT_HISTOGRAM].argname)) { do_dechist = false; result = false; } - if (!stats_check_arg_pair(&args[ATTARG_MOST_COMMON_VALS], - &args[ATTARG_MOST_COMMON_FREQS], + if (!stats_check_arg_pair(most_common_vals, most_common_freqs, attarginfo[ATTARG_MOST_COMMON_VALS].argname, attarginfo[ATTARG_MOST_COMMON_FREQS].argname)) { @@ -281,8 +325,7 @@ attribute_statistics_update_internal(Oid reloid, result = false; } - if (!stats_check_arg_pair(&args[ATTARG_MOST_COMMON_ELEMS], - &args[ATTARG_MOST_COMMON_ELEM_FREQS], + if (!stats_check_arg_pair(most_common_elems, most_common_elem_freqs, attarginfo[ATTARG_MOST_COMMON_ELEMS].argname, attarginfo[ATTARG_MOST_COMMON_ELEM_FREQS].argname)) { @@ -290,8 +333,7 @@ attribute_statistics_update_internal(Oid reloid, result = false; } - if (!stats_check_arg_pair(&args[ATTARG_RANGE_LENGTH_HISTOGRAM], - &args[ATTARG_RANGE_EMPTY_FRAC], + if (!stats_check_arg_pair(range_length_histogram, range_empty_frac, attarginfo[ATTARG_RANGE_LENGTH_HISTOGRAM].argname, attarginfo[ATTARG_RANGE_EMPTY_FRAC].argname)) { @@ -367,19 +409,19 @@ attribute_statistics_update_internal(Oid reloid, replaces); /* if specified, set to argument values */ - if (!args[ATTARG_NULL_FRAC].isnull) + if (!null_frac->isnull) { - values[Anum_pg_statistic_stanullfrac - 1] = args[ATTARG_NULL_FRAC].value; + values[Anum_pg_statistic_stanullfrac - 1] = null_frac->value; replaces[Anum_pg_statistic_stanullfrac - 1] = true; } - if (!args[ATTARG_AVG_WIDTH].isnull) + if (!avg_width->isnull) { - values[Anum_pg_statistic_stawidth - 1] = args[ATTARG_AVG_WIDTH].value; + values[Anum_pg_statistic_stawidth - 1] = avg_width->value; replaces[Anum_pg_statistic_stawidth - 1] = true; } - if (!args[ATTARG_N_DISTINCT].isnull) + if (!n_distinct->isnull) { - values[Anum_pg_statistic_stadistinct - 1] = args[ATTARG_N_DISTINCT].value; + values[Anum_pg_statistic_stadistinct - 1] = n_distinct->value; replaces[Anum_pg_statistic_stadistinct - 1] = true; } @@ -387,10 +429,10 @@ attribute_statistics_update_internal(Oid reloid, if (do_mcv) { bool converted; - Datum stanumbers = args[ATTARG_MOST_COMMON_FREQS].value; + Datum stanumbers = most_common_freqs->value; Datum stavalues = statatt_build_stavalues("most_common_vals", &array_in_fn, - args[ATTARG_MOST_COMMON_VALS].value, + most_common_vals->value, atttypid, atttypmod, &converted); @@ -430,7 +472,7 @@ attribute_statistics_update_internal(Oid reloid, stavalues = statatt_build_stavalues("histogram_bounds", &array_in_fn, - args[ATTARG_HISTOGRAM_BOUNDS].value, + histogram_bounds->value, atttypid, atttypmod, &converted); @@ -448,7 +490,7 @@ attribute_statistics_update_internal(Oid reloid, /* STATISTIC_KIND_CORRELATION */ if (do_correlation) { - Datum elems[] = {args[ATTARG_CORRELATION].value}; + Datum elems[] = {correlation->value}; ArrayType *arry = construct_array_builtin(elems, 1, FLOAT4OID); Datum stanumbers = PointerGetDatum(arry); @@ -461,13 +503,13 @@ attribute_statistics_update_internal(Oid reloid, /* STATISTIC_KIND_MCELEM */ if (do_mcelem) { - Datum stanumbers = args[ATTARG_MOST_COMMON_ELEM_FREQS].value; + Datum stanumbers = most_common_elem_freqs->value; bool converted = false; Datum stavalues; stavalues = statatt_build_stavalues("most_common_elems", &array_in_fn, - args[ATTARG_MOST_COMMON_ELEMS].value, + most_common_elems->value, elemtypid, atttypmod, &converted); @@ -485,7 +527,7 @@ attribute_statistics_update_internal(Oid reloid, /* STATISTIC_KIND_DECHIST */ if (do_dechist) { - Datum stanumbers = args[ATTARG_ELEM_COUNT_HISTOGRAM].value; + Datum stanumbers = elem_count_histogram->value; statatt_set_slot(values, nulls, replaces, STATISTIC_KIND_DECHIST, @@ -507,7 +549,7 @@ attribute_statistics_update_internal(Oid reloid, stavalues = statatt_build_stavalues("range_bounds_histogram", &array_in_fn, - args[ATTARG_RANGE_BOUNDS_HISTOGRAM].value, + range_bounds_histogram->value, atttypid, atttypmod, &converted); @@ -527,7 +569,7 @@ attribute_statistics_update_internal(Oid reloid, if (do_range_length_histogram) { /* The anyarray is always a float8[] for this stakind */ - Datum elems[] = {args[ATTARG_RANGE_EMPTY_FRAC].value}; + Datum elems[] = {range_empty_frac->value}; ArrayType *arry = construct_array_builtin(elems, 1, FLOAT4OID); Datum stanumbers = PointerGetDatum(arry); @@ -536,7 +578,7 @@ attribute_statistics_update_internal(Oid reloid, stavalues = statatt_build_stavalues("range_length_histogram", &array_in_fn, - args[ATTARG_RANGE_LENGTH_HISTOGRAM].value, + range_length_histogram->value, FLOAT8OID, 0, &converted); if (converted) @@ -734,7 +776,8 @@ import_attribute_statistics(Relation rel, AttrNumber attnum, bool inherited, const NullableDatum *range_empty_frac, const NullableDatum *range_bounds_histogram) { - LOCAL_FCINFO(newfcinfo, ATTARG_NUM_ATTARGS); + NullableDatum null_datum = {.value = (Datum) 0, .isnull = true}; + Oid reloid = RelationGetRelid(rel); char *relname = RelationGetRelationName(rel); char *attname = get_attname(reloid, attnum, true); @@ -753,6 +796,9 @@ import_attribute_statistics(Relation rel, AttrNumber attnum, bool inherited, Assert(range_empty_frac); Assert(range_bounds_histogram); + if (!version) + version = &null_datum; + /* annoyingly, get_attname doesn't check attisdropped */ if (attname == NULL || !SearchSysCacheExistsAttName(reloid, attname)) @@ -761,39 +807,18 @@ import_attribute_statistics(Relation rel, AttrNumber attnum, bool inherited, errmsg("column %d of relation \"%s\" does not exist", attnum, relname))); - InitFunctionCallInfoData(*newfcinfo, NULL, ATTARG_NUM_ATTARGS, - InvalidOid, NULL, NULL); - - newfcinfo->args[ATTARG_ATTRELSCHEMA].value = - CStringGetTextDatum(get_namespace_name(RelationGetNamespace(rel))); - newfcinfo->args[ATTARG_ATTRELSCHEMA].isnull = false; - newfcinfo->args[ATTARG_ATTRELNAME].value = CStringGetTextDatum(relname); - newfcinfo->args[ATTARG_ATTRELNAME].isnull = false; - newfcinfo->args[ATTARG_ATTNAME].value = CStringGetTextDatum(attname); - newfcinfo->args[ATTARG_ATTNAME].isnull = false; - newfcinfo->args[ATTARG_ATTNUM].value = Int16GetDatum(attnum); - newfcinfo->args[ATTARG_ATTNUM].isnull = false; - newfcinfo->args[ATTARG_INHERITED].value = BoolGetDatum(inherited); - newfcinfo->args[ATTARG_INHERITED].isnull = false; - - newfcinfo->args[ATTARG_VERSION].value = (version) ? version->value : (Datum) 0; - newfcinfo->args[ATTARG_VERSION].isnull = (version) ? version->isnull : true; - newfcinfo->args[ATTARG_NULL_FRAC] = *null_frac; - newfcinfo->args[ATTARG_AVG_WIDTH] = *avg_width; - newfcinfo->args[ATTARG_N_DISTINCT] = *n_distinct; - newfcinfo->args[ATTARG_MOST_COMMON_VALS] = *most_common_vals; - newfcinfo->args[ATTARG_MOST_COMMON_FREQS] = *most_common_freqs; - newfcinfo->args[ATTARG_HISTOGRAM_BOUNDS] = *histogram_bounds; - newfcinfo->args[ATTARG_CORRELATION] = *correlation; - newfcinfo->args[ATTARG_MOST_COMMON_ELEMS] = *most_common_elems; - newfcinfo->args[ATTARG_MOST_COMMON_ELEM_FREQS] = *most_common_elem_freqs; - newfcinfo->args[ATTARG_ELEM_COUNT_HISTOGRAM] = *elem_count_histogram; - newfcinfo->args[ATTARG_RANGE_LENGTH_HISTOGRAM] = *range_length_histogram; - newfcinfo->args[ATTARG_RANGE_EMPTY_FRAC] = *range_empty_frac; - newfcinfo->args[ATTARG_RANGE_BOUNDS_HISTOGRAM] = *range_bounds_histogram; - return attribute_statistics_update_internal(reloid, attname, attnum, - inherited, newfcinfo->args); + inherited, version, + null_frac, avg_width, + n_distinct, most_common_vals, + most_common_freqs, + histogram_bounds, correlation, + most_common_elems, + most_common_elem_freqs, + elem_count_histogram, + range_length_histogram, + range_empty_frac, + range_bounds_histogram); } /* diff --git a/src/backend/statistics/extended_stats_funcs.c b/src/backend/statistics/extended_stats_funcs.c index 0c84160a824..58692bcf1f0 100644 --- a/src/backend/statistics/extended_stats_funcs.c +++ b/src/backend/statistics/extended_stats_funcs.c @@ -311,6 +311,11 @@ upsert_pg_statistic_ext_data(const Datum *values, const bool *nulls, * like when the statistics object or its schema do not exist, a conversion * failure on one statistic kind, or when other statistic kinds may still * be updated. + * + * Unlike its attribute and relation equivalent functions, there is no + * corresponding extended_statistics_update_internal() function. This is mostly + * because there is not yet an internal update use-case where the statitics + * object is already locked. */ static bool extended_statistics_update(const NullableDatum *args) diff --git a/src/backend/statistics/relation_stats.c b/src/backend/statistics/relation_stats.c index 2e62cf5b9e3..99432502245 100644 --- a/src/backend/statistics/relation_stats.c +++ b/src/backend/statistics/relation_stats.c @@ -63,7 +63,11 @@ static struct StatsArgInfo relarginfo[] = static bool relation_statistics_update(const NullableDatum *args); static bool relation_statistics_update_internal(Oid reloid, - const NullableDatum *args); + const NullableDatum *version, + const NullableDatum *relpages, + const NullableDatum *reltuples, + const NullableDatum *relallvisible, + const NullableDatum *relallfrozen); /* * Internal function for modifying statistics for a relation. @@ -92,22 +96,32 @@ relation_statistics_update(const NullableDatum *args) ShareUpdateExclusiveLock, 0, RangeVarCallbackForStats, &locked_table); - return relation_statistics_update_internal(reloid, args); + return relation_statistics_update_internal(reloid, + &args[RELARG_VERSION], + &args[RELARG_RELPAGES], + &args[RELARG_RELTUPLES], + &args[RELARG_RELALLVISIBLE], + &args[RELARG_RELALLFROZEN]); } /* * Workhorse function for relation_statistics_update. */ static bool -relation_statistics_update_internal(Oid reloid, const NullableDatum *args) +relation_statistics_update_internal(Oid reloid, + const NullableDatum *version, + const NullableDatum *relpages, + const NullableDatum *reltuples, + const NullableDatum *relallvisible, + const NullableDatum *relallfrozen) { - BlockNumber relpages = 0; + BlockNumber num_relpages = 0; bool update_relpages = false; - float reltuples = 0; + float num_reltuples = 0; bool update_reltuples = false; - BlockNumber relallvisible = 0; + BlockNumber num_relallvisible = 0; bool update_relallvisible = false; - BlockNumber relallfrozen = 0; + BlockNumber num_relallfrozen = 0; bool update_relallfrozen = false; Relation crel; HeapTuple ctup; @@ -118,23 +132,29 @@ relation_statistics_update_internal(Oid reloid, const NullableDatum *args) int nreplaces = 0; bool result = true; - if (!args[RELARG_RELPAGES].isnull) + Assert(version); + Assert(relpages); + Assert(reltuples); + Assert(relallvisible); + Assert(relallfrozen); + + if (!relpages->isnull) { - relpages = DatumGetUInt32(args[RELARG_RELPAGES].value); + num_relpages = DatumGetUInt32(relpages->value); update_relpages = true; } - if (!args[RELARG_RELTUPLES].isnull) + if (!reltuples->isnull) { - reltuples = DatumGetFloat4(args[RELARG_RELTUPLES].value); - if (isnan(reltuples) || isinf(reltuples)) + num_reltuples = DatumGetFloat4(reltuples->value); + if (isnan(num_reltuples) || isinf(num_reltuples)) { ereport(WARNING, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("argument \"%s\" must be a finite value", "reltuples"))); result = false; } - else if (reltuples < -1.0) + else if (num_reltuples < -1.0) { ereport(WARNING, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), @@ -145,15 +165,15 @@ relation_statistics_update_internal(Oid reloid, const NullableDatum *args) update_reltuples = true; } - if (!args[RELARG_RELALLVISIBLE].isnull) + if (!relallvisible->isnull) { - relallvisible = DatumGetUInt32(args[RELARG_RELALLVISIBLE].value); + num_relallvisible = DatumGetUInt32(relallvisible->value); update_relallvisible = true; } - if (!args[RELARG_RELALLFROZEN].isnull) + if (!relallfrozen->isnull) { - relallfrozen = DatumGetUInt32(args[RELARG_RELALLFROZEN].value); + num_relallfrozen = DatumGetUInt32(relallfrozen->value); update_relallfrozen = true; } @@ -169,31 +189,31 @@ relation_statistics_update_internal(Oid reloid, const NullableDatum *args) pgcform = (Form_pg_class) GETSTRUCT(ctup); - if (update_relpages && relpages != pgcform->relpages) + if (update_relpages && num_relpages != pgcform->relpages) { replaces[nreplaces] = Anum_pg_class_relpages; - values[nreplaces] = UInt32GetDatum(relpages); + values[nreplaces] = relpages->value; nreplaces++; } - if (update_reltuples && reltuples != pgcform->reltuples) + if (update_reltuples && num_reltuples != pgcform->reltuples) { replaces[nreplaces] = Anum_pg_class_reltuples; - values[nreplaces] = Float4GetDatum(reltuples); + values[nreplaces] = reltuples->value; nreplaces++; } - if (update_relallvisible && relallvisible != pgcform->relallvisible) + if (update_relallvisible && num_relallvisible != pgcform->relallvisible) { replaces[nreplaces] = Anum_pg_class_relallvisible; - values[nreplaces] = UInt32GetDatum(relallvisible); + values[nreplaces] = relallvisible->value; nreplaces++; } - if (update_relallfrozen && relallfrozen != pgcform->relallfrozen) + if (update_relallfrozen && num_relallfrozen != pgcform->relallfrozen) { replaces[nreplaces] = Anum_pg_class_relallfrozen; - values[nreplaces] = UInt32GetDatum(relallfrozen); + values[nreplaces] = relallfrozen->value; nreplaces++; } @@ -225,26 +245,24 @@ relation_statistics_update_internal(Oid reloid, const NullableDatum *args) Datum pg_clear_relation_stats(PG_FUNCTION_ARGS) { - LOCAL_FCINFO(newfcinfo, RELARG_NUM_RELARGS); - - InitFunctionCallInfoData(*newfcinfo, NULL, 6, InvalidOid, NULL, NULL); - - newfcinfo->args[RELARG_SCHEMA].value = PG_GETARG_DATUM(RELARG_SCHEMA); - newfcinfo->args[RELARG_SCHEMA].isnull = PG_ARGISNULL(RELARG_SCHEMA); - newfcinfo->args[RELARG_RELNAME].value = PG_GETARG_DATUM(RELARG_RELNAME); - newfcinfo->args[RELARG_RELNAME].isnull = PG_ARGISNULL(RELARG_RELNAME); - newfcinfo->args[RELARG_VERSION].value = (Datum) 0; - newfcinfo->args[RELARG_VERSION].isnull = true; - newfcinfo->args[RELARG_RELPAGES].value = UInt32GetDatum(0); - newfcinfo->args[RELARG_RELPAGES].isnull = false; - newfcinfo->args[RELARG_RELTUPLES].value = Float4GetDatum(-1.0); - newfcinfo->args[RELARG_RELTUPLES].isnull = false; - newfcinfo->args[RELARG_RELALLVISIBLE].value = UInt32GetDatum(0); - newfcinfo->args[RELARG_RELALLVISIBLE].isnull = false; - newfcinfo->args[RELARG_RELALLFROZEN].value = UInt32GetDatum(0); - newfcinfo->args[RELARG_RELALLFROZEN].isnull = false; - - relation_statistics_update(newfcinfo->args); + NullableDatum args[RELARG_NUM_RELARGS]; + + args[RELARG_SCHEMA].value = PG_GETARG_DATUM(RELARG_SCHEMA); + args[RELARG_SCHEMA].isnull = PG_ARGISNULL(RELARG_SCHEMA); + args[RELARG_RELNAME].value = PG_GETARG_DATUM(RELARG_RELNAME); + args[RELARG_RELNAME].isnull = PG_ARGISNULL(RELARG_RELNAME); + args[RELARG_VERSION].value = (Datum) 0; + args[RELARG_VERSION].isnull = true; + args[RELARG_RELPAGES].value = UInt32GetDatum(0); + args[RELARG_RELPAGES].isnull = false; + args[RELARG_RELTUPLES].value = Float4GetDatum(-1.0); + args[RELARG_RELTUPLES].isnull = false; + args[RELARG_RELALLVISIBLE].value = UInt32GetDatum(0); + args[RELARG_RELALLVISIBLE].isnull = false; + args[RELARG_RELALLFROZEN].value = UInt32GetDatum(0); + args[RELARG_RELALLFROZEN].isnull = false; + + relation_statistics_update(args); PG_RETURN_VOID(); } @@ -279,30 +297,18 @@ import_relation_statistics(Relation rel, const NullableDatum *relallvisible, const NullableDatum *relallfrozen) { - LOCAL_FCINFO(newfcinfo, RELARG_NUM_RELARGS); + NullableDatum null_datum = {.value = (Datum) 0, .isnull = true}; Assert(relpages); Assert(reltuples); Assert(relallvisible); Assert(relallfrozen); - InitFunctionCallInfoData(*newfcinfo, NULL, RELARG_NUM_RELARGS, - InvalidOid, NULL, NULL); - - newfcinfo->args[RELARG_SCHEMA].value = - CStringGetTextDatum(get_namespace_name(RelationGetNamespace(rel))); - newfcinfo->args[RELARG_SCHEMA].isnull = false; - newfcinfo->args[RELARG_RELNAME].value = - CStringGetTextDatum(RelationGetRelationName(rel)); - newfcinfo->args[RELARG_RELNAME].isnull = false; - newfcinfo->args[RELARG_VERSION].value = (version) ? version->value : (Datum) 0; - newfcinfo->args[RELARG_VERSION].isnull = (version) ? version->isnull : true; - - newfcinfo->args[RELARG_RELPAGES] = *relpages; - newfcinfo->args[RELARG_RELTUPLES] = *reltuples; - newfcinfo->args[RELARG_RELALLVISIBLE] = *relallvisible; - newfcinfo->args[RELARG_RELALLFROZEN] = *relallfrozen; - - return relation_statistics_update_internal(RelationGetRelid(rel), - newfcinfo->args); + /* Handle optional parameters */ + if (!version) + version = &null_datum; + + return relation_statistics_update_internal(RelationGetRelid(rel), version, + relpages, reltuples, + relallvisible, relallfrozen); } -- 2.50.1 (Apple Git-155)