plan/spec: the operator corpus goes green
102/102. PLAN's M3 row now names both corpora as the gate, because neither the pinned crud suite nor e2e3/e2e4 can see this work: the eight operators are barely in the pinned corpus and `$push`'s modifiers are not in it at all. §6 records what the corpus found that was nobody's operator -- an upsert never reporting the `_id` it generated -- and the three things left open on purpose: `$bit`, a multi-field `$sort` key inside `$push`, and the 64-path bound on the conflict check. Full matrix at this commit: 247/247 unit tests in ReleaseFast and ReleaseSafe, 83/83 fuzz, operators 102/0, positional 51/0, aggregation 70/0, pinned crud 218/73/196 unmoved, e2e and crash-fuzz green.
This commit was merged in pull request #8.
This commit is contained in:
24
PLAN.md
24
PLAN.md
@@ -467,7 +467,7 @@ answers, and the trade is only acceptable because the lie is removed first.
|
|||||||
| M1 | **Cursors + wire polish** | getMore / killCursors / batchSize; server-side cursor state with idle timeout; sessions plumbing (lsid accepted) as drivers send it; hello advertisement updates; **`moreToCome` on requests** (see the bug below); command-monitoring assertions in the spec runner | crud spec suite green; e2e green |
|
| M1 | **Cursors + wire polish** | getMore / killCursors / batchSize; server-side cursor state with idle timeout; sessions plumbing (lsid accepted) as drivers send it; hello advertisement updates; **`moreToCome` on requests** (see the bug below); command-monitoring assertions in the spec runner | crud spec suite green; e2e green |
|
||||||
| M2 | **The `aggregate` command surface** | `$out` and `$merge` (7 of the 13 failures), and refusing every pipeline construct the engine does not implement instead of answering `0` (amendment A6). The other 6 failures are blocked on M2.5, M4 and M8 — see `docs/M2_DESIGN_REVIEW.md` §7 | `aggregate-*.json`: 0 fail among the 7 reachable cases |
|
| M2 | **The `aggregate` command surface** | `$out` and `$merge` (7 of the 13 failures), and refusing every pipeline construct the engine does not implement instead of answering `0` (amendment A6). The other 6 failures are blocked on M2.5, M4 and M8 — see `docs/M2_DESIGN_REVIEW.md` §7 | `aggregate-*.json`: 0 fail among the 7 reachable cases |
|
||||||
| M2.5 | **The aggregation engine** | expression evaluator, per-stage document iterator, the accumulators, `$unwind`; `$lookup`/`$facet` explicitly out of the first cut (amendment A6) | a purpose-built stage corpus, every expectation measured against mongod |
|
| M2.5 | **The aggregation engine** | expression evaluator, per-stage document iterator, the accumulators, `$unwind`; `$lookup`/`$facet` explicitly out of the first cut (amendment A6) | a purpose-built stage corpus, every expectation measured against mongod |
|
||||||
| M3 | **Update operators + index types** | `distinct` (**done**); positional paths refused rather than destructive (**done**); `$`/`$[]`/`$[<ident>]` + `arrayFilters` implemented (**done**); then $setOnInsert, $addToSet, $mul, $min/$max, $pop, $pullAll, $currentDate, pipeline updates; partial + hashed indexes | `tests/spec/positional/` 0 fail (51 cases, recorded from mongod — **green**; the named gate could not see this work, see below); remaining crud coverage; e2e3/e2e4 green |
|
| M3 | **Update operators + index types** | `distinct` (**done**); positional paths refused rather than destructive (**done**); `$`/`$[]`/`$[<ident>]` + `arrayFilters` (**done**); $setOnInsert, $addToSet, $mul, $min/$max, $pop, $pullAll, $currentDate + `$push`'s modifiers (**done**); then pipeline updates; partial + hashed indexes | `tests/spec/positional/` 0 fail (51 cases) and `tests/spec/operators/` 0 fail (102 cases), both recorded from mongod — **green**; the named gate could not see either, see below; remaining crud coverage; e2e3/e2e4 green |
|
||||||
| M4 | **Sessions + transactions** | logical sessions, snapshot isolation on the mmap engine, write concern at commit | sessions + transactions spec suites green |
|
| M4 | **Sessions + transactions** | logical sessions, snapshot isolation on the mmap engine, write concern at commit | sessions + transactions spec suites green |
|
||||||
| M5 | **Change streams** | change feed + resume tokens (likely log-seq based), getMore integration | change-streams spec suite green |
|
| M5 | **Change streams** | change feed + resume tokens (likely log-seq based), getMore integration | change-streams spec suite green |
|
||||||
| M6 | **Admin/ops commands** | dbStats, collStats, serverStatus, ping, buildInfo, listDatabases filters, dropDatabase durability (log it) | mongosh UX smoke; e2e green |
|
| M6 | **Admin/ops commands** | dbStats, collStats, serverStatus, ping, buildInfo, listDatabases filters, dropDatabase durability (log it) | mongosh UX smoke; e2e green |
|
||||||
@@ -1123,6 +1123,28 @@ has to be its own commit with its own re-recorded scorecard.
|
|||||||
agrees. Worth one commit, and it needs its own measurements first: the
|
agrees. Worth one commit, and it needs its own measurements first: the
|
||||||
padding case (`y.3.b` past the end) is a *legal* creation on mongod, so
|
padding case (`y.3.b` past the end) is a *legal* creation on mongod, so
|
||||||
the fix is not "refuse a non-document element".
|
the fix is not "refuse a non-document element".
|
||||||
|
- **M3's second corpus is `tests/spec/operators/`.** The eight operators PLAN
|
||||||
|
§3 names all answered `bad update` with code 2, one message for every
|
||||||
|
question — and `$push`'s `$slice`, `$position` and `$sort` were parsed,
|
||||||
|
accepted and *dropped*. `{$each: [3, 4], $slice: -3}` appended both values,
|
||||||
|
sliced nothing and answered ok: 1 with modifiedCount: 1, which is the same
|
||||||
|
class of wrong answer the positional operators were. 102 cases, recorded red
|
||||||
|
at 18/84 and driven green.
|
||||||
|
|
||||||
|
It found one thing that was nobody's operator: **an upsert never reported the
|
||||||
|
`_id` it generated**. `Engine.insert` writes a generated `_id` into the bytes
|
||||||
|
and leaves the caller's tree without it, so `upsertedId` came back null and
|
||||||
|
`findOneAndUpdate` with `returnDocument: after` returned a document with no
|
||||||
|
`_id` — the only name the client has for a document it has never seen. Fixed
|
||||||
|
in `build_upsert_doc`; the pinned crud corpus never noticed because its
|
||||||
|
upsert cases match `upsertedId` loosely.
|
||||||
|
|
||||||
|
Left open, measured and deliberate: `$bit` is not implemented (mongod has it,
|
||||||
|
no driver in `tests/` sends it, and it is not in the M3 row); `$sort` inside
|
||||||
|
`$push` accepts only a one-field key document, where mongod allows several;
|
||||||
|
and the conflict check stops after 64 distinct paths in one update rather
|
||||||
|
than refusing a legal wide update.
|
||||||
|
|
||||||
- **M3 update operators** — open. `distinct` landed first because it was a
|
- **M3 update operators** — open. `distinct` landed first because it was a
|
||||||
whole missing command with no dependencies, and measuring it turned up three
|
whole missing command with no dependencies, and measuring it turned up three
|
||||||
things worth keeping, none of which are `distinct`'s to fix:
|
things worth keeping, none of which are `distinct`'s to fix:
|
||||||
|
|||||||
@@ -58,21 +58,27 @@ as a bare number would not have said so.
|
|||||||
|
|
||||||
## Where it stands
|
## Where it stands
|
||||||
|
|
||||||
Recorded against mongod 8.3.7, run against the server before any of it was
|
Recorded against mongod 8.3.7. Green:
|
||||||
implemented:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
array-ops.json 2 pass 24 fail 0 skip
|
array-ops.json 26 pass 0 fail 0 skip
|
||||||
current-date.json 3 pass 8 fail 0 skip
|
current-date.json 11 pass 0 fail 0 skip
|
||||||
modifiers.json 7 pass 7 fail 0 skip
|
modifiers.json 14 pass 0 fail 0 skip
|
||||||
numeric.json 0 pass 21 fail 0 skip
|
numeric.json 21 pass 0 fail 0 skip
|
||||||
push-modifiers.json 6 pass 15 fail 0 skip
|
push-modifiers.json 21 pass 0 fail 0 skip
|
||||||
set-on-insert.json 0 pass 9 fail 0 skip
|
set-on-insert.json 9 pass 0 fail 0 skip
|
||||||
```
|
```
|
||||||
|
|
||||||
Red by construction. The 18 that pass are the shapes this server already
|
It was recorded red — 18 pass / 84 fail against a server with none of these
|
||||||
answers the way mongod does — mostly refusals that happen to agree, plus the
|
operators — and driven green by seven commits. The 18 that passed then were
|
||||||
`$push` cases with no modifier on them.
|
the shapes this server already answered mongod's way, mostly refusals that
|
||||||
|
happened to agree.
|
||||||
|
|
||||||
|
It also found a bug nothing else here had: an upsert never reported the `_id`
|
||||||
|
it generated, so `updateOne(..., {upsert: true}).upsertedId` was null and
|
||||||
|
`findOneAndUpdate` with `returnDocument: after` returned a document with no
|
||||||
|
`_id`. This is the first corpus here that upserts into an empty collection and
|
||||||
|
then looks at what came back.
|
||||||
|
|
||||||
## What recording it settled
|
## What recording it settled
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user