Skip to content

test: native_groupagg_batch gets its pytest twin, and a decline shape the node stops taking is a red, not a skip (#1341) - #1485

Merged
jdatcmd merged 2 commits into
mainfrom
test/1341-native-groupagg-batch-twin
Oct 16, 2026
Merged

jdatcmd merged 2 commits into
mainfrom
test/1341-native-groupagg-batch-twin

Conversation

@OffgridwithJD

Copy link
Copy Markdown
Collaborator

@jdatcmd Item 74's next twin-less suite: native_groupagg_batch.sh gets test_native_groupagg_batch.py, and the suite is seeded in the ledger.

The twin, red first and name for name

All 69 checks by the shell's name, in eight tests. Under each of twelve mutations of the grouped fold, the twin reddens exactly the shell's set. I read that with a scratch runner that records every red and carries on, which also answers your masking note on #1482: the full set is compared, not only each test's first red.

mutation (columnar_vector.c) reds, shell = twin
the grouped fold never called (the removal proof) 12, every work-done arm
float8 admitted as a bitwise key 2, the -0.0/0.0 arms
delete mask ignored 5
a skipped vector's present slots not consumed 2
no scan key applied per row 4
by-value gate dropped (text key reaches the gather) 2
exactness gate dropped (<> folded) 2
min/max admitted as fold kinds 1
expression-key gate dropped 2
partial node without the shared counter 2
ANALYZE prints the prediction (#602's shape) 1
grouped path refuses a text key 1

Two of these make the columnar query error (by-value and expression-key). The shell names those reds through pgc_fail and an empty fold value, while the first draft of the twin raised and named nothing. Its helpers now read an error as a value.

Five-major runs at head: 69/69 for the shell and 69/69 for the twin, on each of 15–19.

Two shell changes

  • The decline arms can no longer skip. When the grouped node wasn't planned for a decline shape, the arm read check_skip. That never fired on 15–19, and with the node gone the gate under test is unreachable, so the skip was a silent pass. Red first, with the planner refusing a text key:
    • old suite: 68 passed + 0 failed + 1 skipped, rc 0;
    • new suite: text key: the fold declined is red, and the twin agrees.
  • A rename. "skipped vectors: four payload columns all stay in step" read only the fold's yes/no. The next arm checks the sums, and only the fold-removal mutation reddened this one. It's now "skipped vectors: the fold ran on the four-payload arm". The suite had no ledger rows, so nothing else is renamed.

I also checked the add-column answer arm, which wraps the grouped query in an outer sum, the very shape the suite warns about for float8. Its plan does keep the grouped node (row path, "Batch Fold: no"), so the arm is sound.

Ledger

Census 4171 / 2980 never / 1191 dated (on main f1fa632d), with suites_not_covered 201 → 200. 31 of the 69 checks are dated. gate --against origin/main gives rc 0, and orphan-scan finds 0. 38 arrive never:

  • 16 premises and the 2 float8 fixture facts;
  • the 8 "grouped node is planned" arms and 2 parallel plan arms, which no fold mutation reaches;
  • 7 heap-mirror oracles (plain, two keys, float8, count(*), timestamp, date, min/max) that none of these mutations moves;
  • the <> count, read by an ungrouped count(*);
  • the add-column prediction and answer.

The mutant logs come from the tree just before the rebase over #1479, which changed only lib.sh's stamp key.

Collection gives cluster_tests 710 -> 718, and TESTS.md gets §165. The guards pass 438/438 and the grader 40/40.

🤖 Generated with Claude Code

jdatcmd and others added 2 commits October 16, 2026 15:06
… the node stops taking is a red, not a skip (#1341)

test_native_groupagg_batch.py carries all 69 checks by the shell's name in
eight tests. Under each of twelve mutations of the grouped fold, the twin
reddens exactly the shell's set of checks, by name. A query that errors is
read as a value, not raised, because two of the mutations (the by-value
gate and the expression-key gate dropped) make the columnar query fail.
Without that the twin errored and named nothing.

The shell changes in two places:
- The decline arms. When the grouped node was not planned, the arm
  read check_skip. It never fired on 15-19, and with the node gone the gate
  under test is unreachable, so the skip was a silent pass. It is now a red
  under the arm's own name. Measured with the planner refusing a text key:
  the old suite reports 68 passed + 1 skipped and exits 0, the new one
  reddens "text key: the fold declined".
- A rename. "skipped vectors: four payload columns all stay in step" read
  only the fold's yes/no; the next arm compares the sums. Only the
  fold-removal mutation reddens it, so it is now "skipped vectors: the fold
  ran on the four-payload arm". The suite had no ledger rows.

COMPLETE gains native_groupagg_batch, and its literal tables join the
loop-reader guard's list. TESTS.md section 165, cluster_tests 710 -> 718.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…twelve grouped-fold mutations (#1341)

The suite had no rows. suites_not_covered 201 -> 200; census 4171 rows /
2980 never / 1191 dated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@jdatcmd jdatcmd left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approve, at 831628d.

My own mutant, different from your twelve: in the batch fold's gather (columnar_vector.c, the loop before the pgcolumnar_groupagg_lookup call at :6157), drop the NULL flag: keynulls[k] = false. That folds the NULL-key group into k = 0 on the batch path only; the row path at :6277 keeps it. PG17:

twin reds
shell 9: plain, filtered, two keys, count(*) and deletes against the heap mirror; toggle-differential plain, filtered and two keys; parallel against the heap mirror
pytest 4: plain, deletes, toggle-differential plain, parallel (the rest masked by first-red; it's the same set, which your carry-on runner showed)

One thing for the ledger, not blocking. Three of those reds are rows this PR enters as never: plain: answers match the heap mirror, two keys: answers match the heap mirror and count(*): answers match the heap mirror. Your description says none of your mutations moves the seven heap-mirror oracles; this one moves three of them. If you want, merge a log from this mutant to date them (a follow-up is fine too).

Also checked: the three-dot diff holds only the 7 files in your stat. The check_skip → red change for an unplanned decline shape is the right direction: a gate that can't be reached is a red.

@OffgridwithJD

Copy link
Copy Markdown
Collaborator Author

@jdatcmd Thanks, your NULL-key mutant is a good one. I reproduced it on PG18 in my parity harness. keynulls[k] = false in the fold's gather gives 9 shell reds, and the soft-expect twin reddens the same 9 by name. That includes plain, two keys and count(*) against the heap mirror, which this PR enters as never.

#1484 and #1486 both touch the ledger, so this PR (and #1487 on top of it) needs a restate when they land. I'll merge this mutant's log in that restate, so those three rows arrive dated. I'll also correct the description's "seven heap-mirror oracles that none of these mutations moves" to four, and post the new heads for re-approval.

🤖 Generated with Claude Code

@jdatcmd

jdatcmd commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator

@OffgridwithJD, merging #1485 now: approved at 831628d, 15/15 green, CLEAN. #1487 follows once it's green.

@jdatcmd
jdatcmd merged commit 2c661ed into main Oct 16, 2026
15 checks passed
@jdatcmd

jdatcmd commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator

@OffgridwithJD, a note on order: I merged #1485 before #1484 and #1486, because #1487 is stacked on it and merging mine first would have made you restate both. So #1485 needs no restate. I'll re-anchor #1484 and #1486 on 2c661ed myself and post their new heads.

The three heap-mirror rows (plain, two keys, count(*)) are still never on main. Two options; either works for me:

#1487 is approved at 53543d7, and I'll merge it once its checks are green.

OffgridwithJD pushed a commit that referenced this pull request Oct 16, 2026
…y mutation from #1485's review (#1341)

jdatcmd's mutation drops the NULL-key flag in the grouped fold's gather,
so the NULL group folds into k = 0 on the batch path only. Nine checks
redden, and the twin reddens the same nine by name. Three entered never
(plain, two keys and count(*) against the heap mirror) and are now dated;
the other six gain the mutation in their history. Census 4189 rows / 2969
never / 1220 dated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants