pg_dump: Adjust reltuples from 0 to -1 for dumps of older versions.
authorNathan Bossart <nathan@postgresql.org>
Thu, 22 May 2025 15:23:26 +0000 (10:23 -0500)
committerNathan Bossart <nathan@postgresql.org>
Thu, 22 May 2025 15:23:26 +0000 (10:23 -0500)
commit5d6eac80cdce7aa7c5f4ec74208ddc1feea9eef3
treeec8aaf8a7d414b8d7dff27d5db47adb8e1b0fcb0
parent1722d5eb05d8e5d2e064cd1798abcae4f296ca9d
pg_dump: Adjust reltuples from 0 to -1 for dumps of older versions.

Before v14, a reltuples value of 0 was ambiguous: it could either
mean the relation is empty, or it could mean that it hadn't yet
been vacuumed or analyzed.  (Commit 3d351d916b taught v14 and newer
to use -1 for the latter case.)  This ambiguity allegedly can cause
the planner to choose inefficient plans after restoring to v18 or
newer.  To fix, let's just dump reltuples as -1 in that case.  This
will cause some truly empty tables to be seen as not-yet-processed,
but that seems unlikely to cause too much trouble in practice.

Note that we could alternatively teach pg_restore_relation_stats()
to translate reltuples based on the version argument, but since
that function doesn't exist until v18, there's no particular
advantage to that approach.  That is, there's no chance of
restoring stats dumped from a pre-v14 server to another pre-v14
server.  Per discussion, the current policy is to fix pre-v18
behavior differences during export and everything else during
import.

Commit 9879105024 fixed a similar problem for vacuumdb by removing
the check for reltuples != 0.  Presumably we could reinstate that
check now, but I've chosen to leave it in place in case reltuples
isn't accurate.  As before, processing some empty tables seems
relatively harmless.

Author: Hari Krishna Sunder <hari.db.pg@gmail.com>
Reviewed-by: Jeff Davis <pgsql@j-davis.com>
Reviewed-by: Corey Huinker <corey.huinker@gmail.com>
Discussion: https://postgr.es/m/CAAeiqZ0o2p4SX5_xPcuAbbsmXjg6MJLNuPYSLUjC%3DWh-VeW64A%40mail.gmail.com
src/bin/pg_dump/pg_dump.c