From 79564c6211d7dd8f80062d9acbcea20969698803 Mon Sep 17 00:00:00 2001 From: Corey Huinker Date: Mon, 22 Jun 2026 14:48:12 -0400 Subject: [PATCH v2 7/7] Make callers of update_attstats() use stats_acquire_relation_lock(). This is the same change that was made in relation_stats.c, but with the function renaming already done beforehand. --- src/backend/statistics/attribute_stats.c | 109 +++++++++++------------ 1 file changed, 51 insertions(+), 58 deletions(-) diff --git a/src/backend/statistics/attribute_stats.c b/src/backend/statistics/attribute_stats.c index 7dccce83c65..f903d2c0003 100644 --- a/src/backend/statistics/attribute_stats.c +++ b/src/backend/statistics/attribute_stats.c @@ -33,8 +33,7 @@ #include "utils/syscache.h" /* - * Positional argument numbers, names, and types for - * update_attstats() and pg_restore_attribute_stats(). + * Positional argument numbers, names, and types for update_attstats() */ enum attribute_stats_argnum @@ -106,7 +105,7 @@ static struct StatsArgInfo cleararginfo[] = [C_NUM_ATTRIBUTE_STATS_ARGS] = {0} }; -static bool update_attstats(FunctionCallInfo fcinfo); +static bool update_attstats(Oid reloid, FunctionCallInfo fcinfo); 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); @@ -128,15 +127,12 @@ static bool delete_pg_statistic(Oid reloid, AttrNumber attnum, bool stainherit); * and other statistic kinds may still be updated. */ static bool -update_attstats(FunctionCallInfo fcinfo) +update_attstats(Oid reloid, FunctionCallInfo fcinfo) { - char *nspname; char *relname; - Oid reloid; char *attname; AttrNumber attnum; bool inherited; - Oid locked_table = InvalidOid; Relation starel; HeapTuple statup; @@ -173,20 +169,8 @@ update_attstats(FunctionCallInfo fcinfo) stats_check_required_arg(fcinfo, attarginfo, ATTRELSCHEMA_ARG); stats_check_required_arg(fcinfo, attarginfo, ATTRELNAME_ARG); - nspname = TextDatumGetCString(PG_GETARG_DATUM(ATTRELSCHEMA_ARG)); relname = TextDatumGetCString(PG_GETARG_DATUM(ATTRELNAME_ARG)); - if (RecoveryInProgress()) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("recovery is in progress"), - errhint("Statistics cannot be modified during recovery."))); - - /* lock before looking up attribute */ - reloid = RangeVarGetRelidExtended(makeRangeVar(nspname, relname, -1), - ShareUpdateExclusiveLock, 0, - RangeVarCallbackForStats, &locked_table); - /* user can specify either attname or attnum, but not both */ if (!PG_ARGISNULL(ATTNAME_ARG)) { @@ -605,7 +589,6 @@ pg_clear_attribute_stats(PG_FUNCTION_ARGS) char *attname; AttrNumber attnum; bool inherited; - Oid locked_table = InvalidOid; stats_check_required_arg(fcinfo, cleararginfo, C_ATTRELSCHEMA_ARG); stats_check_required_arg(fcinfo, cleararginfo, C_ATTRELNAME_ARG); @@ -614,16 +597,7 @@ pg_clear_attribute_stats(PG_FUNCTION_ARGS) nspname = TextDatumGetCString(PG_GETARG_DATUM(C_ATTRELSCHEMA_ARG)); relname = TextDatumGetCString(PG_GETARG_DATUM(C_ATTRELNAME_ARG)); - - if (RecoveryInProgress()) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("recovery is in progress"), - errhint("Statistics cannot be modified during recovery."))); - - reloid = RangeVarGetRelidExtended(makeRangeVar(nspname, relname, -1), - ShareUpdateExclusiveLock, 0, - RangeVarCallbackForStats, &locked_table); + reloid = stats_acquire_relation_lock(nspname, relname); attname = TextDatumGetCString(PG_GETARG_DATUM(C_ATTNAME_ARG)); attnum = get_attnum(reloid, attname); @@ -677,6 +651,9 @@ pg_restore_attribute_stats(PG_FUNCTION_ARGS) { LOCAL_FCINFO(positional_fcinfo, NUM_ATTRIBUTE_STATS_ARGS); bool result = true; + Oid reloid; + char *nspname; + char *relname; InitFunctionCallInfoData(*positional_fcinfo, NULL, NUM_ATTRIBUTE_STATS_ARGS, InvalidOid, NULL, NULL); @@ -685,7 +662,15 @@ pg_restore_attribute_stats(PG_FUNCTION_ARGS) attarginfo)) result = false; - if (!update_attstats(positional_fcinfo)) + stats_check_required_arg(positional_fcinfo, attarginfo, ATTRELSCHEMA_ARG); + stats_check_required_arg(positional_fcinfo, attarginfo, ATTRELNAME_ARG); + + nspname = TextDatumGetCString(positional_fcinfo->args[ATTRELSCHEMA_ARG].value); + relname = TextDatumGetCString(positional_fcinfo->args[ATTRELNAME_ARG].value); + + reloid = stats_acquire_relation_lock(nspname, relname); + + if (!update_attstats(reloid, positional_fcinfo)) result = false; PG_RETURN_BOOL(result); @@ -835,48 +820,56 @@ attribute_statistics_update(Relation rel, const char *attname, const char *range_empty_frac, const char *range_bounds_histogram) { - LOCAL_FCINFO(newfcinfo, NUM_ATTRIBUTE_STATS_ARGS); + LOCAL_FCINFO(positional_fcinfo, NUM_ATTRIBUTE_STATS_ARGS); + Oid reloid; + char *nspname; + char *relname; - InitFunctionCallInfoData(*newfcinfo, NULL, NUM_ATTRIBUTE_STATS_ARGS, InvalidOid, NULL, NULL); + InitFunctionCallInfoData(*positional_fcinfo, NULL, NUM_ATTRIBUTE_STATS_ARGS, InvalidOid, NULL, NULL); + + nspname = get_namespace_name(RelationGetNamespace(rel)); + relname = RelationGetRelationName(rel); + + reloid = stats_acquire_relation_lock(nspname, relname); /* * Convert all string inputs to their required datatypes. NULL values are * left as the default. */ - newfcinfo->args[ATTRELSCHEMA_ARG].value = CStringGetTextDatum(get_namespace_name(RelationGetNamespace(rel))); - newfcinfo->args[ATTRELSCHEMA_ARG].isnull = false; - newfcinfo->args[ATTRELNAME_ARG].value = CStringGetTextDatum(RelationGetRelationName(rel)); - newfcinfo->args[ATTRELNAME_ARG].isnull = false; + positional_fcinfo->args[ATTRELSCHEMA_ARG].value = CStringGetTextDatum(nspname); + positional_fcinfo->args[ATTRELSCHEMA_ARG].isnull = false; + positional_fcinfo->args[ATTRELNAME_ARG].value = CStringGetTextDatum(relname); + positional_fcinfo->args[ATTRELNAME_ARG].isnull = false; - set_text_arg(&newfcinfo->args[ATTNAME_ARG], attname); + set_text_arg(&positional_fcinfo->args[ATTNAME_ARG], attname); if (attnum != InvalidAttrNumber) { - newfcinfo->args[ATTNUM_ARG].value = Int16GetDatum(attnum); - newfcinfo->args[ATTNUM_ARG].isnull = false; + positional_fcinfo->args[ATTNUM_ARG].value = Int16GetDatum(attnum); + positional_fcinfo->args[ATTNUM_ARG].isnull = false; } else { - newfcinfo->args[ATTNUM_ARG].value = (Datum) 0; - newfcinfo->args[ATTNUM_ARG].isnull = true; + positional_fcinfo->args[ATTNUM_ARG].value = (Datum) 0; + positional_fcinfo->args[ATTNUM_ARG].isnull = true; } - newfcinfo->args[INHERITED_ARG].value = BoolGetDatum(inherited); - newfcinfo->args[INHERITED_ARG].isnull = false; + positional_fcinfo->args[INHERITED_ARG].value = BoolGetDatum(inherited); + positional_fcinfo->args[INHERITED_ARG].isnull = false; - set_float_arg(&newfcinfo->args[NULL_FRAC_ARG], null_frac); - set_int32_arg(&newfcinfo->args[AVG_WIDTH_ARG], avg_width); - set_float_arg(&newfcinfo->args[N_DISTINCT_ARG], n_distinct); - set_text_arg(&newfcinfo->args[MOST_COMMON_VALS_ARG], most_common_vals); - set_floatarr_arg(&newfcinfo->args[MOST_COMMON_FREQS_ARG], most_common_freqs); - set_text_arg(&newfcinfo->args[HISTOGRAM_BOUNDS_ARG], histogram_bounds); - set_float_arg(&newfcinfo->args[CORRELATION_ARG], correlation); - set_text_arg(&newfcinfo->args[MOST_COMMON_ELEMS_ARG], most_common_elems); - set_floatarr_arg(&newfcinfo->args[MOST_COMMON_ELEM_FREQS_ARG], most_common_elem_freqs); - set_floatarr_arg(&newfcinfo->args[ELEM_COUNT_HISTOGRAM_ARG], elem_count_histogram); - set_text_arg(&newfcinfo->args[RANGE_LENGTH_HISTOGRAM_ARG], range_length_histogram); - set_float_arg(&newfcinfo->args[RANGE_EMPTY_FRAC_ARG], range_empty_frac); - set_text_arg(&newfcinfo->args[RANGE_BOUNDS_HISTOGRAM_ARG], range_bounds_histogram); + set_float_arg(&positional_fcinfo->args[NULL_FRAC_ARG], null_frac); + set_int32_arg(&positional_fcinfo->args[AVG_WIDTH_ARG], avg_width); + set_float_arg(&positional_fcinfo->args[N_DISTINCT_ARG], n_distinct); + set_text_arg(&positional_fcinfo->args[MOST_COMMON_VALS_ARG], most_common_vals); + set_floatarr_arg(&positional_fcinfo->args[MOST_COMMON_FREQS_ARG], most_common_freqs); + set_text_arg(&positional_fcinfo->args[HISTOGRAM_BOUNDS_ARG], histogram_bounds); + set_float_arg(&positional_fcinfo->args[CORRELATION_ARG], correlation); + set_text_arg(&positional_fcinfo->args[MOST_COMMON_ELEMS_ARG], most_common_elems); + set_floatarr_arg(&positional_fcinfo->args[MOST_COMMON_ELEM_FREQS_ARG], most_common_elem_freqs); + set_floatarr_arg(&positional_fcinfo->args[ELEM_COUNT_HISTOGRAM_ARG], elem_count_histogram); + set_text_arg(&positional_fcinfo->args[RANGE_LENGTH_HISTOGRAM_ARG], range_length_histogram); + set_float_arg(&positional_fcinfo->args[RANGE_EMPTY_FRAC_ARG], range_empty_frac); + set_text_arg(&positional_fcinfo->args[RANGE_BOUNDS_HISTOGRAM_ARG], range_bounds_histogram); - return update_attstats(newfcinfo); + return update_attstats(reloid, positional_fcinfo); } -- 2.54.0