commands: the stages that rewrite a document
`$addFields`, `$set`, `$unset`, `$replaceRoot` and `$unwind`. The corpus goes
0 pass / 24 fail to 21 / 3, and the three left are `$project`'s computed
fields, renames and nested inclusions, which want the `query.project` that
`find` shares and are their own change.
**The design review was wrong about what this needed, and the corpus is what
settled it.** Tier 2 was scoped as a per-stage iterator on the grounds that
`$unwind` is 1->N and "there is no way to express that in a window over the
input". That was true of the window as it stood, and stopped being true the
moment `$project` was made to rebuild the stream instead of moving bounds over
it -- a stage that rebuilds can emit as many documents as it likes, or none. So
all five share one shape: read the window, build a new list, replace the
stream. No iterator, no rewrite.
What the recording settled, and what a hand-written test would have got wrong:
- `$addFields` whose expression resolves to nothing leaves the field out
entirely rather than setting it to null -- so `set_path` is only reached
when there is a value, and `eval_expr`'s absent/null distinction earns its
keep a second time.
- `$addFields: {"n.z": 1}` sets the nested path and keeps its siblings, and
an existing field is replaced *where it stands*, which is what makes the
stage "add or overwrite" rather than "append".
- `$unwind` drops a document whose field is missing or an empty array, keeps
one whose field is not an array *whole*, and numbers `includeArrayIndex`
from zero. Three separate behaviours where one guess would have covered
them all wrongly.
- `$replaceRoot` of a missing path and of a non-document are the same error,
40228.
`ReplaceRootNotDocument` joins `EvalError` rather than being reported at the
stage: it is a failure only a document can produce, which is the line that set
already draws.
191/191 unit tests in ReleaseFast and ReleaseSafe, 83/83 fuzz, e2e 49, e2e3 16,
e2e4 17, e2e6 72, e2e7 86, crud corpus unchanged at 201/90/196.
This commit is contained in:
@@ -64,7 +64,7 @@ accumulators in:
|
||||
```
|
||||
group-accumulators.json 19 pass 0 fail 0 skip
|
||||
expressions.json 27 pass 0 fail 0 skip
|
||||
document-stages.json 0 pass 24 fail 0 skip
|
||||
document-stages.json 21 pass 3 fail 0 skip
|
||||
```
|
||||
|
||||
`group-accumulators` found its first real disagreement on the way to 18:
|
||||
@@ -73,10 +73,11 @@ that counted documents rather than numbers would have passed every test
|
||||
anybody would think to write by hand.
|
||||
|
||||
`expressions.json` was recorded before the evaluator was written and read
|
||||
1 pass / 26 fail against it; it is green now. `document-stages.json` is the
|
||||
next tier's spec, recorded and not implemented -- `$addFields`/`$set`,
|
||||
`$unset`, `$replaceRoot`, `$unwind` and `$project`'s computed fields, none of
|
||||
which this server has, so it starts at zero.
|
||||
1 pass / 26 fail against it; it is green now. `document-stages.json` was recorded at
|
||||
0 pass / 24 fail; `$addFields`/`$set`, `$unset`, `$replaceRoot` and `$unwind`
|
||||
took it to 21. The three left are `$project`'s computed fields, its renames and
|
||||
its nested inclusions, which want the shared `query.project` and are their own
|
||||
change.
|
||||
|
||||
What recording *that* settled:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user