Files
MultiforaDB/tests/spec/operators/push-modifiers.json
A.Shakhmatov eaf8d7c677 tests/spec: a recorded corpus for the update operators
PLAN §3 lists eight operators for M3 -- `$setOnInsert`, `$addToSet`, `$mul`,
`$min`, `$max`, `$pop`, `$pullAll`, `$currentDate` -- and the pinned crud
corpus says almost nothing about any of them. A probe running the identical
update against mongod 8.3.7 and this server found all eight answering
`bad update`, code 2, one message for every question.

It also found the thing this directory exists for: `$push`'s `$slice`,
`$position` and `$sort` are **silently ignored**. `{$each: [3, 4], $slice: -3}`
appends both values, slices nothing, and answers ok: 1 with modifiedCount: 1.
A missing operator is an error the client can see; a modifier that is parsed,
accepted and then dropped is the same class of wrong answer the positional
operators were.

103 cases in six files, 18 pass / 84 fail -- red by construction, like
`tests/spec/aggregate/expressions.json` at 1/26 and the positional corpus at
15/36. Inputs authored in `sources/`, every expectation measured.

Two things here cannot be recorded as values, and both become a `$$type`
assertion rather than being left out: a `$currentDate` field is whatever the
clock said (named per case in `volatile`, so a real stored date can still be
pinned one day), and an upsert that inserts gets a generated ObjectId (that
one automatic -- no source authors an ObjectId). Everything else is compared
exactly. Files are canonical extended JSON, which the runner already parses
that way: `$mul` overflowing an int32 produces an int64, and writing
`4000000000` as a bare number would not have said so.

What recording it settled, none of it guessable:

  - `$mul` of a missing field writes **0**, not the operand; of a non-numeric
    field, or by one, TypeMismatch (14).
  - `$min`/`$max` are not numeric operators. They compare in BSON canonical
    order, so `$min: {s: 5}` on `s: "b"` writes 5, and a missing field is
    always written.
  - two operators writing one field is **ConflictingUpdateOperators (40)** --
    `$min`+`$max`, `$set`+`$inc`, `$setOnInsert`+`$set`. A whole error class
    this server does not have.
  - `$addToSet` compares documents whole, **field order included**:
    `{a:1,b:2}` and `{b:2,a:1}` are two values. But `2` and `2.0` are one.
  - `$push` modifiers are only modifiers when `$each` is there: `{$slice: 1}`
    alone is a value to push. With it, the order is position, then sort the
    whole array, then slice.
  - `$currentDate` with `false` still writes a date.
  - `$setOnInsert` may write `_id` on an insert, where `$set` may not.
  - an unknown modifier is FailedToParse (9), not BadValue.

One case was authored and then removed: `{b: 1, $set: {c: 1}}` never reaches a
server -- the driver rejects it -- so there was no answer to record and the
case would have asserted nothing.
2026-08-10 21:02:51 +03:00

2 lines
12 KiB
JSON

{"description":"push-modifiers","schemaVersion":"1.4","createEntities":[{"client":{"id":"client0"}},{"database":{"id":"database0","client":"client0","databaseName":"operator-corpus"}},{"collection":{"id":"collection0","database":"database0","collectionName":"coll"}}],"initialData":[{"collectionName":"coll","databaseName":"operator-corpus","documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"1"},{"$numberInt":"2"}]}]}],"tests":[{"description":"$slice keeps the last n","operations":[{"object":"collection0","name":"updateOne","arguments":{"filter":{},"update":{"$push":{"t":{"$each":[{"$numberInt":"3"},{"$numberInt":"4"}],"$slice":{"$numberInt":"-3"}}}}},"expectResult":{"matchedCount":{"$numberInt":"1"},"modifiedCount":{"$numberInt":"1"},"upsertedCount":{"$numberInt":"0"}}}],"outcome":[{"collectionName":"coll","databaseName":"operator-corpus","documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"2"},{"$numberInt":"3"},{"$numberInt":"4"}]}]}]},{"description":"$slice keeps the first n","operations":[{"object":"collection0","name":"updateOne","arguments":{"filter":{},"update":{"$push":{"t":{"$each":[{"$numberInt":"3"},{"$numberInt":"4"}],"$slice":{"$numberInt":"3"}}}}},"expectResult":{"matchedCount":{"$numberInt":"1"},"modifiedCount":{"$numberInt":"1"},"upsertedCount":{"$numberInt":"0"}}}],"outcome":[{"collectionName":"coll","databaseName":"operator-corpus","documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"1"},{"$numberInt":"2"},{"$numberInt":"3"}]}]}]},{"description":"$slice of zero empties the array","operations":[{"object":"collection0","name":"updateOne","arguments":{"filter":{},"update":{"$push":{"t":{"$each":[{"$numberInt":"3"}],"$slice":{"$numberInt":"0"}}}}},"expectResult":{"matchedCount":{"$numberInt":"1"},"modifiedCount":{"$numberInt":"1"},"upsertedCount":{"$numberInt":"0"}}}],"outcome":[{"collectionName":"coll","databaseName":"operator-corpus","documents":[{"_id":{"$numberInt":"1"},"t":[]}]}]},{"description":"$slice larger than the array keeps all of it","operations":[{"object":"collection0","name":"updateOne","arguments":{"filter":{},"update":{"$push":{"t":{"$each":[{"$numberInt":"3"}],"$slice":{"$numberInt":"10"}}}}},"expectResult":{"matchedCount":{"$numberInt":"1"},"modifiedCount":{"$numberInt":"1"},"upsertedCount":{"$numberInt":"0"}}}],"outcome":[{"collectionName":"coll","databaseName":"operator-corpus","documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"1"},{"$numberInt":"2"},{"$numberInt":"3"}]}]}]},{"description":"$slice with an empty $each truncates without adding","operations":[{"object":"collection0","name":"updateOne","arguments":{"filter":{},"update":{"$push":{"t":{"$each":[],"$slice":{"$numberInt":"1"}}}}},"expectResult":{"matchedCount":{"$numberInt":"1"},"modifiedCount":{"$numberInt":"1"},"upsertedCount":{"$numberInt":"0"}}}],"outcome":[{"collectionName":"coll","databaseName":"operator-corpus","documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"1"}]}]}]},{"description":"$position inserts at the front","operations":[{"object":"collection0","name":"updateOne","arguments":{"filter":{},"update":{"$push":{"t":{"$each":[{"$numberInt":"9"}],"$position":{"$numberInt":"0"}}}}},"expectResult":{"matchedCount":{"$numberInt":"1"},"modifiedCount":{"$numberInt":"1"},"upsertedCount":{"$numberInt":"0"}}}],"outcome":[{"collectionName":"coll","databaseName":"operator-corpus","documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"9"},{"$numberInt":"1"},{"$numberInt":"2"}]}]}]},{"description":"$position inserts in the middle","operations":[{"object":"collection0","name":"updateOne","arguments":{"filter":{},"update":{"$push":{"t":{"$each":[{"$numberInt":"9"}],"$position":{"$numberInt":"1"}}}}},"expectResult":{"matchedCount":{"$numberInt":"1"},"modifiedCount":{"$numberInt":"1"},"upsertedCount":{"$numberInt":"0"}}}],"outcome":[{"collectionName":"coll","databaseName":"operator-corpus","documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"1"},{"$numberInt":"9"},{"$numberInt":"2"}]}]}]},{"description":"$position past the end appends","operations":[{"object":"collection0","name":"updateOne","arguments":{"filter":{},"update":{"$push":{"t":{"$each":[{"$numberInt":"9"}],"$position":{"$numberInt":"99"}}}}},"expectResult":{"matchedCount":{"$numberInt":"1"},"modifiedCount":{"$numberInt":"1"},"upsertedCount":{"$numberInt":"0"}}}],"outcome":[{"collectionName":"coll","databaseName":"operator-corpus","documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"1"},{"$numberInt":"2"},{"$numberInt":"9"}]}]}]},{"description":"$position counted from the end","operations":[{"object":"collection0","name":"updateOne","arguments":{"filter":{},"update":{"$push":{"t":{"$each":[{"$numberInt":"9"}],"$position":{"$numberInt":"-1"}}}}},"expectResult":{"matchedCount":{"$numberInt":"1"},"modifiedCount":{"$numberInt":"1"},"upsertedCount":{"$numberInt":"0"}}}],"outcome":[{"collectionName":"coll","databaseName":"operator-corpus","documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"1"},{"$numberInt":"9"},{"$numberInt":"2"}]}]}]},{"description":"$sort ascending over scalars","operations":[{"object":"collection0","name":"deleteMany","arguments":{"filter":{}}},{"object":"collection0","name":"insertMany","arguments":{"documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"3"},{"$numberInt":"1"}]}]}},{"object":"collection0","name":"updateOne","arguments":{"filter":{},"update":{"$push":{"t":{"$each":[{"$numberInt":"2"}],"$sort":{"$numberInt":"1"}}}}},"expectResult":{"matchedCount":{"$numberInt":"1"},"modifiedCount":{"$numberInt":"1"},"upsertedCount":{"$numberInt":"0"}}}],"outcome":[{"collectionName":"coll","databaseName":"operator-corpus","documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"1"},{"$numberInt":"2"},{"$numberInt":"3"}]}]}]},{"description":"$sort descending over scalars","operations":[{"object":"collection0","name":"deleteMany","arguments":{"filter":{}}},{"object":"collection0","name":"insertMany","arguments":{"documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"3"},{"$numberInt":"1"}]}]}},{"object":"collection0","name":"updateOne","arguments":{"filter":{},"update":{"$push":{"t":{"$each":[{"$numberInt":"2"}],"$sort":{"$numberInt":"-1"}}}}},"expectResult":{"matchedCount":{"$numberInt":"1"},"modifiedCount":{"$numberInt":"1"},"upsertedCount":{"$numberInt":"0"}}}],"outcome":[{"collectionName":"coll","databaseName":"operator-corpus","documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"3"},{"$numberInt":"2"},{"$numberInt":"1"}]}]}]},{"description":"$sort on a field of the elements","operations":[{"object":"collection0","name":"deleteMany","arguments":{"filter":{}}},{"object":"collection0","name":"insertMany","arguments":{"documents":[{"_id":{"$numberInt":"1"},"t":[{"a":{"$numberInt":"3"}},{"a":{"$numberInt":"1"}}]}]}},{"object":"collection0","name":"updateOne","arguments":{"filter":{},"update":{"$push":{"t":{"$each":[{"a":{"$numberInt":"2"}}],"$sort":{"a":{"$numberInt":"1"}}}}}},"expectResult":{"matchedCount":{"$numberInt":"1"},"modifiedCount":{"$numberInt":"1"},"upsertedCount":{"$numberInt":"0"}}}],"outcome":[{"collectionName":"coll","databaseName":"operator-corpus","documents":[{"_id":{"$numberInt":"1"},"t":[{"a":{"$numberInt":"1"}},{"a":{"$numberInt":"2"}},{"a":{"$numberInt":"3"}}]}]}]},{"description":"$sort and $slice together","operations":[{"object":"collection0","name":"deleteMany","arguments":{"filter":{}}},{"object":"collection0","name":"insertMany","arguments":{"documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"3"},{"$numberInt":"1"}]}]}},{"object":"collection0","name":"updateOne","arguments":{"filter":{},"update":{"$push":{"t":{"$each":[{"$numberInt":"2"}],"$sort":{"$numberInt":"1"},"$slice":{"$numberInt":"2"}}}}},"expectResult":{"matchedCount":{"$numberInt":"1"},"modifiedCount":{"$numberInt":"1"},"upsertedCount":{"$numberInt":"0"}}}],"outcome":[{"collectionName":"coll","databaseName":"operator-corpus","documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"1"},{"$numberInt":"2"}]}]}]},{"description":"$position and $slice together","operations":[{"object":"collection0","name":"updateOne","arguments":{"filter":{},"update":{"$push":{"t":{"$each":[{"$numberInt":"9"}],"$position":{"$numberInt":"0"},"$slice":{"$numberInt":"2"}}}}},"expectResult":{"matchedCount":{"$numberInt":"1"},"modifiedCount":{"$numberInt":"1"},"upsertedCount":{"$numberInt":"0"}}}],"outcome":[{"collectionName":"coll","databaseName":"operator-corpus","documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"9"},{"$numberInt":"1"}]}]}]},{"description":"$slice without $each","operations":[{"object":"collection0","name":"updateOne","arguments":{"filter":{},"update":{"$push":{"t":{"$slice":{"$numberInt":"1"}}}}},"expectResult":{"matchedCount":{"$numberInt":"1"},"modifiedCount":{"$numberInt":"1"},"upsertedCount":{"$numberInt":"0"}}}],"outcome":[{"collectionName":"coll","databaseName":"operator-corpus","documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"1"},{"$numberInt":"2"},{"$slice":{"$numberInt":"1"}}]}]}]},{"description":"$each that is not an array","operations":[{"object":"collection0","name":"updateOne","arguments":{"filter":{},"update":{"$push":{"t":{"$each":{"$numberInt":"3"}}}}},"expectError":{"isError":true,"errorCode":{"$numberInt":"2"}}}],"outcome":[{"collectionName":"coll","databaseName":"operator-corpus","documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"1"},{"$numberInt":"2"}]}]}]},{"description":"$slice that is not a number","operations":[{"object":"collection0","name":"updateOne","arguments":{"filter":{},"update":{"$push":{"t":{"$each":[{"$numberInt":"3"}],"$slice":"x"}}}},"expectError":{"isError":true,"errorCode":{"$numberInt":"2"}}}],"outcome":[{"collectionName":"coll","databaseName":"operator-corpus","documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"1"},{"$numberInt":"2"}]}]}]},{"description":"$position that is not a number","operations":[{"object":"collection0","name":"updateOne","arguments":{"filter":{},"update":{"$push":{"t":{"$each":[{"$numberInt":"3"}],"$position":"x"}}}},"expectError":{"isError":true,"errorCode":{"$numberInt":"2"}}}],"outcome":[{"collectionName":"coll","databaseName":"operator-corpus","documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"1"},{"$numberInt":"2"}]}]}]},{"description":"an unknown modifier beside $each","operations":[{"object":"collection0","name":"updateOne","arguments":{"filter":{},"update":{"$push":{"t":{"$each":[{"$numberInt":"3"}],"$bogus":{"$numberInt":"1"}}}}},"expectError":{"isError":true,"errorCode":{"$numberInt":"2"}}}],"outcome":[{"collectionName":"coll","databaseName":"operator-corpus","documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"1"},{"$numberInt":"2"}]}]}]},{"description":"a document operand that is not modifiers at all is a value","operations":[{"object":"collection0","name":"updateOne","arguments":{"filter":{},"update":{"$push":{"t":{"a":{"$numberInt":"1"}}}}},"expectResult":{"matchedCount":{"$numberInt":"1"},"modifiedCount":{"$numberInt":"1"},"upsertedCount":{"$numberInt":"0"}}}],"outcome":[{"collectionName":"coll","databaseName":"operator-corpus","documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"1"},{"$numberInt":"2"},{"a":{"$numberInt":"1"}}]}]}]},{"description":"$push $each onto a missing field","operations":[{"object":"collection0","name":"updateOne","arguments":{"filter":{},"update":{"$push":{"gone":{"$each":[{"$numberInt":"1"},{"$numberInt":"2"}]}}}},"expectResult":{"matchedCount":{"$numberInt":"1"},"modifiedCount":{"$numberInt":"1"},"upsertedCount":{"$numberInt":"0"}}}],"outcome":[{"collectionName":"coll","databaseName":"operator-corpus","documents":[{"_id":{"$numberInt":"1"},"t":[{"$numberInt":"1"},{"$numberInt":"2"}],"gone":[{"$numberInt":"1"},{"$numberInt":"2"}]}]}]}]}