On Sat, Sep 19, 2026 at 2:00 PM Corey Huinker <[email protected]> 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 least once, and if that's genuinely the case then perhaps we > should address that, but that would have implications outside of 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 explicitly unsupported state (modified to > empty but not analyzed), and the situation will resolve itself when the > remote table is 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 case where 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
