On Thu, Sep 10, 2026 at 3:59 PM Fujii Masao <[email protected]> wrote: > postgres_fdw stats import seems to have several potential issues.
> (1) User-defined functions may be executed with unexpected privileges > > ANALYZE on a foreign table with import_stats disabled invokes > user-defined functions (e.g., domain constraints) as the foreign table's > owner. But, with import_stats enabled, they are invoked as the user > running ANALYZE. So, if that user is a superuser, those functions would > be run with superuser privileges. Could this be a security issue? Sorry, I don't follow this. Could you elaborate on it using an example? > (2) COLLATE is not supported by old remote servers > > Stats import sends COLLATE "C" to the remote server without checking > its version, but COLLATE is supported only in v9.1 and later. > The comment in deparse.c explicitly mentions this compatibility issue, and > IMPORT FOREIGN SCHEMA disables collation import for remote servers older > than v9.1. > > So, it seems stats import should handle this issue as well, e.g., either by > avoiding COLLATE or by falling back to sampling. Good catch! I feel like just falling back to sampling. > (3) n_distinct is ignored > > Stats import ignores the foreign table column's n_distinct option, whereas > normal ANALYZE applies it after collecting statistics. > > IMO, n_distinct should also be applied to imported stats. Rather than making the code complicated for that, I feel like just copying the remote table's stats as-proposed, as in most cases, those stats are generated on the remote server under the correct settings of parameters like n_distcint. How about adding a note about that? > (4) Imported relpages may use different block sizes > > Stats import stores the remote relpages value unchanged, whereas the > normal ANALYZE uses pg_relation_size() divided by the local BLCKSZ to > handle the case where the block sizes differ between the local and remote > servers. > > We should convert the imported page count to local block units, for example? Good point! Actually, this is a known issue in the normal ANALYZE: /* * Construct SELECT statement to acquire size in blocks of given relation. * * Note: we use local definition of block size, not remote definition. * This is perhaps debatable. * * Note: pg_relation_size() exists in 8.1 and later. */ void deparseAnalyzeSizeSql(StringInfo buf, Relation rel) >From a cost calculation perspective, I think it's appropriate to use the imported relpages as-is, as it's used to estimate the cost for remote operations, not local ones, and thus we should actually instead fix the normal-ANALYZE handling to calculate the size based on the remote definition of block size. Thanks for the report! Best regards, Etsuro Fujita
