pub fn recognize_atom(value: ParseValue, position: AtomPosition) -> ParseValueExpand description
Rebuild a recognized __type envelope on an otherwise-raw value. Never recurses.
The asymmetry this preserves is upstream’s, measured at the pin against an $in over an array
field:
| operand | upstream |
|---|---|
| element is a Pointer | matches |
| element is a Pointer plus an unknown key | still matches |
| Pointer nested in a plain object | matches |
| Pointer nested in a plain object, plus an unknown key | does not match |
Upstream reconstructs a recognized atom from its declared keys, so an extra key on the atom
itself is discarded and cannot affect the comparison, while a plain object is returned untouched
and is therefore compared whole. Decoding all the way down, which is what classify does,
collapses those two rows into one: the nested extra key is dropped, the operand compares equal,
and the query matches a row upstream does not return.
A value that is already a decoded atom is returned unchanged, so a constraint built in Rust rather than parsed from a request passes through untouched.
Payload validation here is stricter than upstream’s, deliberately. Every coder’s
isValidJSON is the tag test and nothing else (MongoTransform.js, the five *Coder objects),
so upstream converts a malformed envelope instead of declining it, and what it converts it to is
not worth reproducing. Measured against a running server at the pin: {"__type":"Date"} becomes
an Invalid Date and matches nothing, {"__type":"GeoPoint"} becomes [null, null] and matches
nothing, {"__type":"Pointer","className":"C"} compares against the literal string
C$undefined, {"__type":"File"} yields undefined and so compares as null, matching rows
where the field is null or absent, and {"__type":"Bytes"} raises a Node TypeError rather
than a Parse error, which is a 500. Every one of those is a comparison against a value the
client never wrote, or a crash.
Declining to recognize a malformed envelope leaves it a plain object, which the caller then refuses with upstream’s own 107 for a non-atom. Narrowing in every case, which is the safe direction: parse-rust refuses where upstream answers with a garbage match. Recorded as a Tier 2 divergence.
An earlier version of this note called the File case a broadening bug that returned every row,
and cited the security carve-out. That was wrong, and wrong in an instructive way: it read
JSON.stringify dropping an undefined key as the key being absent from the query. The driver
serializes it as null, so the constraint is applied and narrows. A rendering is not a
behavior. Verified against a live server rather than against a transform’s return value.