From 395b73c045e02bbe5a33c10f57f528a4468a56f4 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Fri, 16 Jan 2026 15:24:59 +0900 Subject: [PATCH] Improve pg_clear_extended_stats() with incorrect relation/stats combination Issue fat-fingered in d756fa1019ff, noticed while doing more review of the main patch set proposed. I have missed the fact that this can be triggered by specifying an extended stats object that does not match with the relation specified and already locked. Like the cases where an object defined in input is missing, the code is changed to issue a WARNING instead of a confusing cache lookup failure. A regression test is added to cover this case. Discussion: https://postgr.es/m/CADkLM=dpz3KFnqP-dgJ-zvRvtjsa8UZv8wDAQdqho=qN3kX0Zg@mail.gmail.com --- src/backend/statistics/extended_stats_funcs.c | 11 +++++++++-- src/test/regress/expected/stats_import.out | 12 ++++++++++++ src/test/regress/sql/stats_import.sql | 6 ++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/backend/statistics/extended_stats_funcs.c b/src/backend/statistics/extended_stats_funcs.c index 22b9750ce19..b4b1bf26463 100644 --- a/src/backend/statistics/extended_stats_funcs.c +++ b/src/backend/statistics/extended_stats_funcs.c @@ -220,8 +220,15 @@ pg_clear_extended_stats(PG_FUNCTION_ARGS) * started. */ if (stxform->stxrelid != relid) - elog(ERROR, "cache lookup failed for extended stats %u: found relation %u but expected %u", - stxform->oid, stxform->stxrelid, relid); + { + table_close(pg_stext, RowExclusiveLock); + ereport(WARNING, + errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not clear extended statistics object \"%s\".\"%s\": incorrect relation \"%s\".\"%s\" specified", + get_namespace_name(nspoid), stxname, + relnspname, relname)); + PG_RETURN_VOID(); + } delete_pg_statistic_ext_data(stxform->oid, inherited); heap_freetuple(tup); diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out index 68ddd619edb..d61ab92d17b 100644 --- a/src/test/regress/expected/stats_import.out +++ b/src/test/regress/expected/stats_import.out @@ -1443,6 +1443,18 @@ WARNING: could not find extended statistics object "stats_import"."ext_stats_no (1 row) +-- Incorrect relation/extended stats combination +SELECT pg_clear_extended_stats(schemaname => 'stats_import', + relname => 'test', + statistics_schemaname => 'stats_import', + statistics_name => 'test_stat_clone', + inherited => false); +WARNING: could not clear extended statistics object "stats_import"."test_stat_clone": incorrect relation "stats_import"."test" specified + pg_clear_extended_stats +------------------------- + +(1 row) + -- Check that records are removed after a valid clear call. SELECT COUNT(*), e.inherited FROM pg_stats_ext AS e WHERE e.statistics_schemaname = 'stats_import' AND diff --git a/src/test/regress/sql/stats_import.sql b/src/test/regress/sql/stats_import.sql index 04d15202e65..d1934a8a42b 100644 --- a/src/test/regress/sql/stats_import.sql +++ b/src/test/regress/sql/stats_import.sql @@ -1044,6 +1044,12 @@ SELECT pg_clear_extended_stats(schemaname => 'stats_import', statistics_schemaname => 'stats_import', statistics_name => 'ext_stats_not_exist', inherited => false); +-- Incorrect relation/extended stats combination +SELECT pg_clear_extended_stats(schemaname => 'stats_import', + relname => 'test', + statistics_schemaname => 'stats_import', + statistics_name => 'test_stat_clone', + inherited => false); -- Check that records are removed after a valid clear call. SELECT COUNT(*), e.inherited FROM pg_stats_ext AS e