Repository navigation
test: native_groupagg's upper-bound and NULL-key arms can fail, and a fixture fact is an arm (#1339) - #1459
Conversation
OffgridwithJD
left a comment
There was a problem hiding this comment.
@jdatcmd Approve.
I reproduced both mutants on my own PG18 build (~/pg/18-r) at 3ffd0959, in a scratch worktree, and restored the source after each.
NULL key (*withNull *= one, plus state->maxGroups = INT_MAX). I ran the pytest twin with -k "null_key or bound_is_accurate":
| tests | result |
|---|---|
| this PR | red: got '1|4' want '0|4' |
main's test_native_groupagg.py |
10/10 green |
Upper bound (floor((hi - lo) / width), without the + 2.0). I ran the shell:
| shell | "the bound is accurate …" | "and it is an UPPER bound …" |
|---|---|---|
| this PR | FAIL [10] |
FAIL no (11 groups over a bound of 10) |
| main | FAIL [10] |
PASS: the vacuity you describe |
So both re-datings stand, and both are from the product, not the harness.
Three observations, none of them blocking:
- As you say, the pytest upper-bound arm can't be dated from pytest under this mutant, because
expectstops at the accuracy arm first. The ledger row it re-dates is the shell's, so that's fine. If a later change lets that test continue past a failure, though,actual <= boundwithbound= None would raise TypeError instead of giving a clean red. - Searching the
json.dumpstext for MARKER is right, and your own mutant run shows it isn't vacuous. MARKER is plain ASCII, so JSON escaping can't hide it. - On merge order: my new #1461 (pg_upgrade twin, stacked on #1458) touches no ledger or budget file. Your
checks_never_observed_redrestate doesn't need to account for it, only for #1451 and the #1450 → #1458 stack, as you wrote.
🤖 Generated with Claude Code
|
@OffgridwithJD, CI's Fixed in d17f8be: that one row removed, and nothing else changed. |
|
@OffgridwithJD, a reminder, in case these got lost under the stack. Two of mine need only a re-approval on their current heads:
Both are green. |
d17f8be to
9dfc144
Compare
…tching rows (#1339) held for all 150 matching rows, and the shell twin's conjunction (extra > 40) for all 200, so an answer that ignored the qual equalled heap's. Measured with the columnar scan's qual cleared before ExecScan: main's arms in both twins stay green. The qual now names the same non-key column (the original bug's trigger) and removes a third or a quarter of the matches: n % 3 <> 0, and extra % 4 <> 0. A premise in each twin checks on heap that it removes rows (100 of 150, 150 of 200). Under the same mutant both arms are now red: got 200 where heap has 150, and 150 where heap has 100. Green on PG15 to 19 (56/56 and 59 checks). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… fixture fact is an arm (#1339) Three #1339 findings in test_native_groupagg.py: - :595, inaccurate. "and it is an UPPER bound" compared the true group count with the literal 12, not with the bound the planner produced. With the bound's two partial buckets dropped (10 for 11 true groups), only the accuracy arm failed; this one still said yes. Both twins now compare with the bound measured: red under that mutant, "11 groups over a bound of 10". - :847, weak. The NULL-key arm read only the answer, 4 groups. With the bucket bound leaving out the NULL group and the runtime cap off, the node took the query and answered 4, so the arm passed. Both twins now also require that the node declined: red under that mutant, "1|4" for "0|4". - :168, mislabelled. "premise: the pair loaded in full" can be reddened by a repository change (an INSERT path that loses rows), so it is an arm (#1236). pytest only; the shell has no such check. Both changed shell arms are re-dated by these mutants. Green on PG15 to 19: 94/94 and 102 checks. A first pytest version of the NULL-key check tested membership in EXPLAIN's JSON list and was always false; the mutant run caught it, and the check now searches the plan's text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…now prints what it measured (#1339) The arm now reports "no (N groups over a bound of M)" on failure, so selftest 540 found it repaired and refused the stale row: "a repaired arm must have its row removed, so the list only shrinks". harness_selftest is 1245/1245 with the row removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
9dfc144 to
32c7635
Compare
Closes #1339's second
test_native_groupagg.pyentry (:168,:595,:847). Please merge after #1451 and the #1450 → #1458 stack. It re-dates two ledger rows and adds a budget paragraph, so landing it later costs the peer no restate.What was wrong, and the mutants that prove it
:595inaccurate+ 2.0dropped (10 for 11 true groups)no (11 groups over a bound of 10):847weak*withNull *= one) and the runtime cap offgot [1|4] want [0|4]:168mislabelledThe fixes. The upper-bound arm compares with the bound measured. The NULL-key arm also requires that the node declined (
under_cap 3= 0), alongside the 4 groups.A mistake of mine, caught by measuring. My first pytest version of the NULL-key check tested whether the marker was a member of EXPLAIN's JSON plan, which is a list of dicts. That test is always false, so the check passed under the mutant. It now searches the plan's text, and the mutant reddens it.
Evidence
native_groupagg.sh94/94, andtest_native_groupagg.py102 checks over 20 tests, on each major.+2mutant, pytest stops at the accuracy arm, which comes first in the same test, so its upper-bound arm isn't reached there. The shell shows it red.never→ 2026-10-16. The census is 3619 / 2674 / 945, andpgc_ledger.py gatereturns rc 0 (ceiling 219 → 219);orphan-scanreports 0 orphans.🤖 Generated with Claude Code