• Tom Lane's avatar
    Redefine pg_class.reltuples to be -1 before the first VACUUM or ANALYZE. · 3d351d91
    Tom Lane authored
    Historically, we've considered the state with relpages and reltuples
    both zero as indicating that we do not know the table's tuple density.
    This is problematic because it's impossible to distinguish "never yet
    vacuumed" from "vacuumed and seen to be empty".  In particular, a user
    cannot use VACUUM or ANALYZE to override the planner's normal heuristic
    that an empty table should not be believed to be empty because it is
    probably about to get populated.  That heuristic is a good safety
    measure, so I don't care to abandon it, but there should be a way to
    override it if the table is indeed intended to stay empty.
    
    Hence, represent the initial state of ignorance by setting reltuples
    to -1 (relpages is still set to zero), and apply the minimum-ten-pages
    heuristic only when reltuples is still -1.  If the table is empty,
    VACUUM or ANALYZE (but not CREATE INDEX) will override that to
    reltuples = relpages = 0, and then we'll plan on that basis.
    
    This requires a bunch of fiddly little changes, but we can get rid of
    some ugly kluges that were formerly needed to maintain the old definition.
    
    One notable point is that FDWs' GetForeignRelSize methods will see
    baserel->tuples = -1 when no ANALYZE has been done on the foreign table.
    That seems like a net improvement, since those methods were formerly
    also in the dark about what baserel->tuples = 0 really meant.  Still,
    it is an API change.
    
    I bumped catversion because code predating this change would get confused
    by seeing reltuples = -1.
    
    Discussion: https://postgr.es/m/F02298E0-6EF4-49A1-BCB6-C484794D9ACC@thebuild.com
    3d351d91
tableam.c 24.4 KB