Skip to content

analyze_function's null_frac premise fails ~1 run in 130: it requires core's sample to miss its own mode #487

Description

@jdatcmd

Hit on the full PG15-19 matrix run for #484, on PG19. No product code was at
fault; the suite failed itself, and it is right to, given how the check is
written. The check should not be written that way.

What happened

FAIL  premise: core's sampled null_frac differs from the truth, so this suite
      can discriminate: got [no (sample landed exactly on truth; suite is vacuous)]
-- core sampled null_frac = 0.1, truth = 0.100000

Every other check in the suite passed, including the one this premise guards
(pgcolumnar.analyze() reports null_frac exactly, from the zone maps).

Why it is not rare enough to ignore

test/analyze_function.sh:123 requires core's SAMPLED null_frac to differ from
the truth, so that "we are exact" is a claim core's number can disagree with.

The fixture is exactly one row in ten NULL, and core samples
300 * default_statistics_target = 30,000 rows. So the sampled NULL count is
binomial with n = 30,000 and p = 0.1, and the check demands that this binomial
not land on its own mode. Landing on 3000 exactly gives null_frac = 0.1,
which equals the truth, and that has probability

1 / sqrt(2 * pi * 30000 * 0.1 * 0.9)  ~=  0.8%

or roughly one run in 130. The suite runs on PG18 and PG19 and is skipped below
18, so that is two draws per matrix.

Measured on six consecutive PG19 runs after the failure, all six passed, with
core's sample at 0.099766664, 0.100833334, 0.10033333, 0.1041, 0.0987 and
0.09786667. The failure is the one draw that lands on the middle.

The same shape is already known here

#475 removed exactly this reasoning for the histogram outlier, and the note reads:

"core misses the outlier" cannot be a gate: it is probabilistic and depends
on our own sampler. Exactness is asserted against an independent
SELECT max() instead, which does not need core to be unlucky.

null_frac kept the old shape. n_distinct at line 168 has it too, though it is
far less exposed, since a sampled distinct estimate landing exactly on 45001 is
much less likely than a binomial landing on its mode.

Fix

Same remedy as #475. The exactness check already compares against an independent
SELECT over the table, so it does not need core to be wrong to mean something.
Either drop the premise to a printed note, or restate it as something that is
true by construction rather than by luck: for example, assert that core's number
came from a SAMPLE (that pg_stats was populated by ANALYZE at all), which is
the property the premise was really reaching for.

Do not "fix" it by loosening the comparison to a tolerance. The point of the
suite is exactness, and a tolerance would let a genuinely approximate result pass.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions