Repository navigation
Legacy query shim edge cases (for 4.0.3) - #33
Merged
Merged
Conversation
…ti replace
_perfect_split_legacy_query treated a $query that isn't a document as an
empty filter, so find() and count() matched every document. It also
merged non-$ fields next to $query into the filter. libmongoc 1.x's
legacy find rejected both ("Cannot mix $query with non-dollar field",
"Invalid BSON in $query subdocument"), and now the shim does too:
count() returns the error, find() returns nil (libmongoc 2 can't hand
back a cursor carrying the error, and MongoCursor exposes no error), and
GridFS list(filter:) throws. A duplicate $query now means the last one
wins, as in 1.x; before, the two were merged. (1.x's legacy count never
unwrapped $query at all; current servers reject a raw $query in count.)
_perfect_collection_count built the legacy find options and threw them
away. hint, maxTimeMS, comment and collation now reach count_documents.
$orderby, $max, $min and the other find-only modifiers are still ignored,
and the doc comment says so. A negative legacy limit is passed as its
absolute value, as the old count command treated it; before, the $limit
stage rejected it. INT64_MIN, which has no absolute value, is an error.
The doc comment also notes that count() can't use $where, $near or
$nearSphere, since count_documents runs the query as a $match.
update() with .multiUpdate and a replacement document replaced one
document and reported success. It now returns an error without writing,
with the server's own message for this case ("multi update is not
supported for replacement-style update"; the server's code is 9, this
is a client-side MONGOC_ERROR_COMMAND_INVALID_ARG).
Tests: 4 new tests. 14 of their checks fail on main (the rest are
baseline checks that pass either way). The comment check uses the
profiler in a database of its own, which it drops, and skips when the
server refuses profiling. All 40 tests pass against mongod 8.3.11 on
macOS (debug and release) and on Linux (Scripts/test-linux.sh).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Edge cases in
Sources/PerfectCMongo/shim.h, the layer that keeps the legacy query API working on libmongoc 2. These were found while reviewing 4.0.2. Intended for a 4.0.3 patch release.1. Invalid legacy
$querydocuments are rejectedTwo cases were accepted silently:
$querythat isn't a document ({$query: 5}) was treated as an empty filter, sofind()andcount()matched every document;$, next to$query, were merged into the filter.libmongoc 1.x's legacy find rejected both (
Cannot mix $query with non-dollar field,Invalid BSON in $query subdocument), and now the shim does too:count()returns the error;find()returnsnil, because libmongoc 2 can't hand back a cursor that carries the error andMongoCursorexposes no error;list(filter:)throws.A duplicate
$querynow means the last one wins, as in 1.x; before, the two were merged.2.
count()options from a legacy query are no longer droppedThe shim built the legacy find options and then threw them away.
$hint,$maxTimeMS,$commentand$collationnow reachcount_documents.$orderby,$max,$minand the other find-only modifiers are still ignored, as before, and the doc comment now says so.limitcounts like a positive one, as the oldcountcommand treated it; before, the$limitstage rejected it.Int.minhas no positive equivalent and is now an error.count()runs as an aggregate$match, so it can't use$where,$nearor$nearSphere. It points to$exprand$geoWithininstead.3.
update(.multiUpdate)with a replacement document is an errorBefore, it replaced one document and reported success. It now returns an error and writes nothing. The message is the server's own wording for this case ("multi update is not supported for replacement-style update"). The server reports it as code 9; here it's a client-side
MONGOC_ERROR_COMMAND_INVALID_ARG.Testing
There are 4 new tests. 14 of their checks fail on
main; the rest are baseline checks that pass either way. The$commenttest uses the profiler in a database of its own, which it drops afterwards, and skips if the server refuses profiling.The full suite (40 tests) passes against mongod 8.3.11 with libmongoc 2.5.5:
Scripts/test-linux.sh.An adversarial review checked these behaviours against the server, against the libmongoc 1.30 and 2.0/2.5 sources, and with an ASan/UBSan probe of the shim. It found no blockers. Two left as-is:
update(updates:)path still replaces one document when given a replacement document, since it has no multi flag;list(filter:)throws a generic error rather than the specific message.🤖 Generated with Claude Code