On Sat, Sep 19, 2026 at 2:00 PM Corey Huinker <corey.huinker@gmail.com> wrote:
>>
>> What is the defense of making all these warnings rather than errors? It's one
>> thing to e.g. warn that analyze skipped a relation due to locks, but doing
>> some catalog updates but not doing everything that the catalog updates
>> depended on seems like a really bad idea. Transactions exist for a reason...
>
> This is more an explanation than a defense, but here it goes...
Thanks for the detailed explanation!
> That's the explanation, what follows is a recap of options of what we can do in the future.
>
> That decision of the analyze.c code to leave existing stats as-is when it gets an empty table sample is curious to
me,as I'm not sure how ANALYZE could ever reflect when a foreign table is actually empty once it has been populated at
leastonce, and if that's genuinely the case then perhaps we should address that, but that would have implications
outsideof this feature, so I'm highly reluctant to do that.
Me too. Users should observe the restrictions when using
postgres_fdw, not just this feature.
> I can foresee several possible courses of action if we choose to reopen this item.
>
> 1. Do nothing, as this is a corner case resulting from a misdesigned foreign table and a remote table in an
explicitlyunsupported state (modified to empty but not analyzed), and the situation will resolve itself when the remote
tableis repopulated, or analyzed, or the column data types are brought into alignment, whichever comes first.
+1
> 2. Consider whether do_analyze_rel should do something (like clear the pg_statistic rows for the relation) in the
casewhere numrows returned from the acquirefunc is zero.
I also thought this option; it would make things logically clean, but
I'm not sure we really need to do so, because in that case we set
reltuples=0 in pg_class, which makes the planner effectively ignore
the remaining attribute stats. See set_baserel_size_estimates(); if
reltuples=0, we have rel->tuples=0, so whatever value
clauselist_selectivity() calculates/returns based on the attribute
stats, rel->rows (the estimated number of output tuples from the base
relation) is set to zero.
Best regards,
Etsuro Fujita