partial.json 3/24 -> 24/24, hashed.json still 0/18. PLAN §6 records the planner rule that is deliberately left conservative -- a partial index is maintained and enforces `unique`, and reads scan until the implication test exists. Full matrix at this commit: 250/250 unit tests in ReleaseFast and ReleaseSafe, 83/83 fuzz, operators 125/0, positional 51/0, aggregation 70/0, pinned crud 228/63/196, e2e and crash-fuzz green.
81 lines
3.4 KiB
Markdown
81 lines
3.4 KiB
Markdown
# The index corpus
|
|
|
|
M3's last row: partial and hashed indexes. `docs/M3_INDEX_TYPES_DESIGN_REVIEW.md`
|
|
measured both against mongod 8.3.7 and found they were not the same kind of
|
|
gap — hashed was honestly refused, `partialFilterExpression` was accepted and
|
|
ignored, and a *unique* partial index therefore refused inserts mongod
|
|
accepts.
|
|
|
|
It also found that **no test in this repository covered that row, in any
|
|
suite**. The pinned corpus is crud and aggregate; `tests/e2e/e2e5.js` and
|
|
`e2e6.js` test indexes and write neither a partial nor a hashed spec. So this
|
|
directory exists for the same reason `tests/spec/positional/` and
|
|
`tests/spec/operators/` do.
|
|
|
|
## The one rule
|
|
|
|
**Inputs are authored here; expectations are measured against a real mongod.**
|
|
|
|
```
|
|
tests/spec/indexes/
|
|
sources/*.json documents + operations, authored
|
|
record.js runs them against mongod, writes the expectations
|
|
*.json generated, unified format, do not hand-edit
|
|
```
|
|
|
|
```sh
|
|
mongod --port 27099 --dbpath <dir>
|
|
node tests/spec/indexes/record.js --mongod-port 27099
|
|
node tests/spec/run.js --suite-dir tests/spec/indexes
|
|
```
|
|
|
|
Unlike the other two corpora, a case here is a **sequence**: create an index,
|
|
insert against it, read back, list it. An index outlives a `deleteMany`, and
|
|
every case is about which indexes exist, so the recorder drops the collection
|
|
between cases and walks each case's operations in order — stopping at the
|
|
first that throws, which is what a client would see.
|
|
|
|
## Where it stands
|
|
|
|
Recorded against mongod 8.3.7 at 3/39 -- red by construction -- and partial
|
|
indexes have since been driven green:
|
|
|
|
```
|
|
hashed.json 0 pass 18 fail 0 skip
|
|
partial.json 24 pass 0 fail 0 skip
|
|
```
|
|
|
|
The three that passed at the start were the reads a partial index does not
|
|
change: this server indexed every document, so a query still found
|
|
everything, which is the whole reason the review called the partial gap
|
|
smaller than the `arrayFilters` one.
|
|
|
|
## What recording it settled
|
|
|
|
Two of the review's own guesses were wrong, which is why it was recorded
|
|
rather than reasoned:
|
|
|
|
| | mongod |
|
|
|---|---|
|
|
| `$in` in a partial filter | **allowed** — the review listed it with `$ne` and `$regex` |
|
|
| same key, different filter, no explicit name | **IndexKeySpecsConflict (86)**, not the 67 the review assumed |
|
|
|
|
And what it confirmed:
|
|
|
|
| | mongod |
|
|
|---|---|
|
|
| a unique partial index | constrains only the documents its filter selects — two `{a: 1, t: false}` are fine, two `{a: 9, t: true}` are E11000 |
|
|
| a document *leaving* the filter | frees the value it held for another document to take |
|
|
| a document *entering* the filter | must take a value nothing inside it holds, or the update is E11000 |
|
|
| `$regex`, `$ne` in a filter | 67 |
|
|
| a filter that is not a document | TypeMismatch (14) |
|
|
| `sparse` + `partialFilterExpression` | 67 — may not be combined |
|
|
| `expireAfterSeconds` + a filter | allowed; `listIndexes` reports the filter *before* the expiry |
|
|
| an empty filter | allowed, and reported |
|
|
| two hashed components | 31303 |
|
|
| `unique` on a hashed index | 16764 |
|
|
| an array at a hashed path | 16766, **at insert time**, not at creation |
|
|
| a key direction that is not 1, -1 or `"hashed"` | 67 |
|
|
| a hashed index beside an ascending one on the same field | both exist |
|
|
| a range query or a sort over a hashed field | still correct — the planner declines the index rather than misusing it |
|