From 5e0a3c7cf741333bf94065616c60074170a84033 Mon Sep 17 00:00:00 2001 From: Corey Huinker Date: Tue, 4 Nov 2025 23:50:01 -0500 Subject: [PATCH v8 5/7] Expose attribute statistics functions for use in extended_stats. Many of the operations of attribute stats have analogous operations in extended stats. * get_attr_stat_type() renamed to statatt_get_type() * init_empty_stats_tuple() renamed to statatt_init_empty_tuple() * text_to_stavalues() * get_elem_stat_type() renamed to statatt_get_elem_type() Also, add comments explaining the function argument index enums, and the arrays that are indexed by those enums. --- src/include/statistics/statistics.h | 17 +++ src/backend/statistics/attribute_stats.c | 126 +++++++++++------------ 2 files changed, 77 insertions(+), 66 deletions(-) diff --git a/src/include/statistics/statistics.h b/src/include/statistics/statistics.h index 7dd0f9755454..0df66b352a10 100644 --- a/src/include/statistics/statistics.h +++ b/src/include/statistics/statistics.h @@ -127,4 +127,21 @@ extern StatisticExtInfo *choose_best_statistics(List *stats, char requiredkind, int nclauses); extern HeapTuple statext_expressions_load(Oid stxoid, bool inh, int idx); +extern void statatt_get_type(Oid reloid, AttrNumber attnum, + Oid *atttypid, int32 *atttypmod, + char *atttyptype, Oid *atttypcoll, + Oid *eq_opr, Oid *lt_opr); +extern void statatt_init_empty_tuple(Oid reloid, int16 attnum, bool inherited, + Datum *values, bool *nulls, bool *replaces); + +extern void statatt_set_slot(Datum *values, bool *nulls, bool *replaces, + int16 stakind, Oid staop, Oid stacoll, + Datum stanumbers, bool stanumbers_isnull, + Datum stavalues, bool stavalues_isnull); + +extern Datum text_to_stavalues(const char *staname, FmgrInfo *array_in, Datum d, + Oid typid, int32 typmod, bool *ok); +extern bool statatt_get_elem_type(Oid atttypid, char atttyptype, + Oid *elemtypid, Oid *elem_eq_opr); + #endif /* STATISTICS_H */ diff --git a/src/backend/statistics/attribute_stats.c b/src/backend/statistics/attribute_stats.c index ef4d768feab7..d0c67a4128e0 100644 --- a/src/backend/statistics/attribute_stats.c +++ b/src/backend/statistics/attribute_stats.c @@ -64,6 +64,10 @@ enum attribute_stats_argnum NUM_ATTRIBUTE_STATS_ARGS }; +/* + * The argument names and typoids of the arguments for + * attribute_statistics_update. + */ static struct StatsArgInfo attarginfo[] = { [ATTRELSCHEMA_ARG] = {"schemaname", TEXTOID}, @@ -101,6 +105,10 @@ enum clear_attribute_stats_argnum C_NUM_ATTRIBUTE_STATS_ARGS }; +/* + * The argument names and typoids of the arguments for + * pg_clear_attribute_stats. + */ static struct StatsArgInfo cleararginfo[] = { [C_ATTRELSCHEMA_ARG] = {"relation", TEXTOID}, @@ -112,23 +120,9 @@ static struct StatsArgInfo cleararginfo[] = static bool attribute_statistics_update(FunctionCallInfo fcinfo); static Node *get_attr_expr(Relation rel, int attnum); -static void get_attr_stat_type(Oid reloid, AttrNumber attnum, - Oid *atttypid, int32 *atttypmod, - char *atttyptype, Oid *atttypcoll, - Oid *eq_opr, Oid *lt_opr); -static bool get_elem_stat_type(Oid atttypid, char atttyptype, - Oid *elemtypid, Oid *elem_eq_opr); -static Datum text_to_stavalues(const char *staname, FmgrInfo *array_in, Datum d, - Oid typid, int32 typmod, bool *ok); -static void set_stats_slot(Datum *values, bool *nulls, bool *replaces, - int16 stakind, Oid staop, Oid stacoll, - Datum stanumbers, bool stanumbers_isnull, - Datum stavalues, bool stavalues_isnull); 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); -static void init_empty_stats_tuple(Oid reloid, int16 attnum, bool inherited, - Datum *values, bool *nulls, bool *replaces); /* * Insert or Update Attribute Statistics @@ -298,16 +292,16 @@ attribute_statistics_update(FunctionCallInfo fcinfo) } /* derive information from attribute */ - get_attr_stat_type(reloid, attnum, - &atttypid, &atttypmod, - &atttyptype, &atttypcoll, - &eq_opr, <_opr); + statatt_get_type(reloid, attnum, + &atttypid, &atttypmod, + &atttyptype, &atttypcoll, + &eq_opr, <_opr); /* if needed, derive element type */ if (do_mcelem || do_dechist) { - if (!get_elem_stat_type(atttypid, atttyptype, - &elemtypid, &elem_eq_opr)) + if (!statatt_get_elem_type(atttypid, atttyptype, + &elemtypid, &elem_eq_opr)) { ereport(WARNING, (errmsg("could not determine element type of column \"%s\"", attname), @@ -361,7 +355,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo) if (HeapTupleIsValid(statup)) heap_deform_tuple(statup, RelationGetDescr(starel), values, nulls); else - init_empty_stats_tuple(reloid, attnum, inherited, values, nulls, + statatt_init_empty_tuple(reloid, attnum, inherited, values, nulls, replaces); /* if specified, set to argument values */ @@ -394,10 +388,10 @@ attribute_statistics_update(FunctionCallInfo fcinfo) if (converted) { - set_stats_slot(values, nulls, replaces, - STATISTIC_KIND_MCV, - eq_opr, atttypcoll, - stanumbers, false, stavalues, false); + statatt_set_slot(values, nulls, replaces, + STATISTIC_KIND_MCV, + eq_opr, atttypcoll, + stanumbers, false, stavalues, false); } else result = false; @@ -417,10 +411,10 @@ attribute_statistics_update(FunctionCallInfo fcinfo) if (converted) { - set_stats_slot(values, nulls, replaces, - STATISTIC_KIND_HISTOGRAM, - lt_opr, atttypcoll, - 0, true, stavalues, false); + statatt_set_slot(values, nulls, replaces, + STATISTIC_KIND_HISTOGRAM, + lt_opr, atttypcoll, + 0, true, stavalues, false); } else result = false; @@ -433,10 +427,10 @@ attribute_statistics_update(FunctionCallInfo fcinfo) ArrayType *arry = construct_array_builtin(elems, 1, FLOAT4OID); Datum stanumbers = PointerGetDatum(arry); - set_stats_slot(values, nulls, replaces, - STATISTIC_KIND_CORRELATION, - lt_opr, atttypcoll, - stanumbers, false, 0, true); + statatt_set_slot(values, nulls, replaces, + STATISTIC_KIND_CORRELATION, + lt_opr, atttypcoll, + stanumbers, false, 0, true); } /* STATISTIC_KIND_MCELEM */ @@ -454,10 +448,10 @@ attribute_statistics_update(FunctionCallInfo fcinfo) if (converted) { - set_stats_slot(values, nulls, replaces, - STATISTIC_KIND_MCELEM, - elem_eq_opr, atttypcoll, - stanumbers, false, stavalues, false); + statatt_set_slot(values, nulls, replaces, + STATISTIC_KIND_MCELEM, + elem_eq_opr, atttypcoll, + stanumbers, false, stavalues, false); } else result = false; @@ -468,10 +462,10 @@ attribute_statistics_update(FunctionCallInfo fcinfo) { Datum stanumbers = PG_GETARG_DATUM(ELEM_COUNT_HISTOGRAM_ARG); - set_stats_slot(values, nulls, replaces, - STATISTIC_KIND_DECHIST, - elem_eq_opr, atttypcoll, - stanumbers, false, 0, true); + statatt_set_slot(values, nulls, replaces, + STATISTIC_KIND_DECHIST, + elem_eq_opr, atttypcoll, + stanumbers, false, 0, true); } /* @@ -494,10 +488,10 @@ attribute_statistics_update(FunctionCallInfo fcinfo) if (converted) { - set_stats_slot(values, nulls, replaces, - STATISTIC_KIND_BOUNDS_HISTOGRAM, - InvalidOid, InvalidOid, - 0, true, stavalues, false); + statatt_set_slot(values, nulls, replaces, + STATISTIC_KIND_BOUNDS_HISTOGRAM, + InvalidOid, InvalidOid, + 0, true, stavalues, false); } else result = false; @@ -521,10 +515,10 @@ attribute_statistics_update(FunctionCallInfo fcinfo) if (converted) { - set_stats_slot(values, nulls, replaces, - STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM, - Float8LessOperator, InvalidOid, - stanumbers, false, stavalues, false); + statatt_set_slot(values, nulls, replaces, + STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM, + Float8LessOperator, InvalidOid, + stanumbers, false, stavalues, false); } else result = false; @@ -584,11 +578,11 @@ get_attr_expr(Relation rel, int attnum) /* * Derive type information from the attribute. */ -static void -get_attr_stat_type(Oid reloid, AttrNumber attnum, - Oid *atttypid, int32 *atttypmod, - char *atttyptype, Oid *atttypcoll, - Oid *eq_opr, Oid *lt_opr) +void +statatt_get_type(Oid reloid, AttrNumber attnum, + Oid *atttypid, int32 *atttypmod, + char *atttyptype, Oid *atttypcoll, + Oid *eq_opr, Oid *lt_opr) { Relation rel = relation_open(reloid, AccessShareLock); Form_pg_attribute attr; @@ -666,9 +660,9 @@ get_attr_stat_type(Oid reloid, AttrNumber attnum, /* * Derive element type information from the attribute type. */ -static bool -get_elem_stat_type(Oid atttypid, char atttyptype, - Oid *elemtypid, Oid *elem_eq_opr) +bool +statatt_get_elem_type(Oid atttypid, char atttyptype, + Oid *elemtypid, Oid *elem_eq_opr) { TypeCacheEntry *elemtypcache; @@ -706,7 +700,7 @@ get_elem_stat_type(Oid atttypid, char atttyptype, * to false. If the resulting array contains NULLs, raise a WARNING and set ok * to false. Otherwise, set ok to true. */ -static Datum +Datum text_to_stavalues(const char *staname, FmgrInfo *array_in, Datum d, Oid typid, int32 typmod, bool *ok) { @@ -759,11 +753,11 @@ text_to_stavalues(const char *staname, FmgrInfo *array_in, Datum d, Oid typid, * Find and update the slot with the given stakind, or use the first empty * slot. */ -static void -set_stats_slot(Datum *values, bool *nulls, bool *replaces, - int16 stakind, Oid staop, Oid stacoll, - Datum stanumbers, bool stanumbers_isnull, - Datum stavalues, bool stavalues_isnull) +void +statatt_set_slot(Datum *values, bool *nulls, bool *replaces, + int16 stakind, Oid staop, Oid stacoll, + Datum stanumbers, bool stanumbers_isnull, + Datum stavalues, bool stavalues_isnull) { int slotidx; int first_empty = -1; @@ -883,9 +877,9 @@ delete_pg_statistic(Oid reloid, AttrNumber attnum, bool stainherit) /* * Initialize values and nulls for a new stats tuple. */ -static void -init_empty_stats_tuple(Oid reloid, int16 attnum, bool inherited, - Datum *values, bool *nulls, bool *replaces) +void +statatt_init_empty_tuple(Oid reloid, int16 attnum, bool inherited, + Datum *values, bool *nulls, bool *replaces) { memset(nulls, true, sizeof(bool) * Natts_pg_statistic); memset(replaces, true, sizeof(bool) * Natts_pg_statistic); -- 2.51.0