Skip to content

Tests for the Mongo semantics the heuristics calculator does not reproduce - #1762

Merged
jgaleotti merged 1 commit into
fix_all_semanticsfrom
tests/mongo-heuristics-semantics-gaps
Sep 16, 2026
Merged

jgaleotti merged 1 commit into
fix_all_semanticsfrom
tests/mongo-heuristics-semantics-gaps

Conversation

@LautaroPetaccio

@LautaroPetaccio LautaroPetaccio commented Sep 14, 2026

Copy link
Copy Markdown
Collaborator

Companion to the review on #1750, one test per defect noted there. Based on fix_all_semantics rather than master, since most of these are about code that only exists on that branch.

Twenty-three tests, added to the section at the end of MongoHeuristicsCalculatorTest that was written for exactly this. Twenty fail and carry @Disabled with the reason, three pass and are there as guards. Every expected value came from a MongoDB 7.0.41 server answering the same query against the same document, so the assertions say what the database does rather than what the documentation implies.

Queries that make the calculator throw

MongoHandler catches nothing around computeDistanceDocuments, so the exception costs the action its whole ExtraHeuristicsDto, the SQL heuristics computed before it included.

Query mongo 7.0.41 calculator
{a:{$regex:"x"}} vs {a:[1,2,3]} 0 documents IllegalArgumentException
{a:{$bitsAllSet: BinData(0,"Ag==")}} vs {a:2} 1 document NullPointerException
{a:{$not:/x/}} vs {a:"aa"} 1 document NullPointerException
{a:{$gt:null}} vs {a:1}, and $gte $lt $lte 0 documents NullPointerException
{a:{$exists:1}} vs {a:1} 1 document NullPointerException
{a:{$mod:[0,0]}} rejects the query ArithmeticException
{a:{$size:-1}} rejects the query NullPointerException

The first row is a regression: the code this PR replaces returned C_FALSE for it. The last four are queries the database answers or refuses on its own terms, and their selectors are untouched here, so they arrive through the route testOperatorsThatAreNotModelledDoNotThrow already documents. $eq and $ne given null answer normally, which is what makes the ordering operators stand out in their own family.

Queries that are answered, but not the way the database answers them

Query mongo 7.0.41 calculator
{a:{$ne:{x:1}}} vs {a:{x:1}} 0 documents match
{a:{$ne:BinData(0,"AQI=")}} vs the same value 0 documents match
{a:{$bitsAllSet:[-1]}} vs {a: Long.MIN_VALUE} rejects the query match
{a:{$bitsAllSet: 3.9}} vs {a:3} rejects the query match
{a:{$bitsAllSet: -1}} vs {a:-1} rejects the query match
{a:{x:1}} vs {a:{x:1}} 1 document no match
{a:{$eq:BinData(0,"AQI=")}} vs the same value 1 document no match
{a:{$all:[1,1]}} vs {a:1} 1 document no match
{a:{$all:[null,null]}} vs {b:1} 1 document no match
{a:{$all:[{$elemMatch:{$gt:2}}]}} vs {a:[1,5]} 1 document no match
{a:{$eq:[1,2]}} vs {a:[[1,2],3]} 1 document no match
{a:{$eq:{$comment:"note",x:1}}} vs the same document 1 document no match
{a:{$in:[/x/]}} vs {a:"xy"} 1 document no match

The rows in bold are the harmful direction, a match the database does not have, which points the search at a condition it can never satisfy.

Two causes account for most of the table. compareNonNullValues has no branch for two sub-documents or two binary values, so they reach the case for types that cannot be compared, which answers false for $eq and true for $ne. On master these threw instead, so this is a step forward that stops short. Separately, nothing validates the bitmask itself, while the field side of the same comparison is validated by getIntegralLongValue.

One that is not about MongoDB semantics

computeDistanceDocuments walks its Iterable three times, and MongoHandler peeks at it once before that. What is passed in today is a FindIterable, which replays, so this is four find round trips per action rather than a wrong answer. The test uses an Iterable that cannot be replayed, which the signature currently accepts, and that one is scored as if the collection were empty while still reporting the documents counted on the first pass.

The three that pass

One beside each group of defects, covering the neighbouring case that is already handled: a byte[] bitmask, $comment at the top level, and $all holding a single null. They are there so a fix can be told apart from a regression in the path next to it.

Running them

Green as they stand. The class runs 174 tests with 25 skipped, 5 of those pre-existing and 20 new. Dropping the new annotations turns those 20 into failures. The whole mongo package is 358 tests, 0 failures, 25 skipped with this branch applied.

…oduce

Twenty queries where the calculator disagrees with the database, and three
neighbouring cases that it already answers correctly, kept as guards so that a
fix can be told apart from a regression in the path next to it.

They extend the section at the end of MongoHeuristicsCalculatorTest, which was
written for exactly this, and follow its convention: every expected value was
taken from a MongoDB 7.0.41 server answering the same query against the same
document, one test per defect, and @disabled with the reason on the ones that
fail today.

Where the database refuses the query outright there is no answer to copy, so
those tests assert that the calculator answers false without throwing, that
being the only answer available to it.

Four of them concern values compareNonNullValues has no branch for, being two
sub-documents or two binary values, which reach the case for types that cannot
be compared. That answers false for $eq, missing the plainest nested-object
query there is, and true for $ne and $nin, which is a match the database does
not have. On master these threw instead, so this is a step forward that stops
short.

Six of the queries make the calculator throw, and MongoHandler catches nothing
around computeDistanceDocuments, so the exception costs the action its whole
ExtraHeuristicsDto, the SQL heuristics included. Two of those six are queries
the database answers normally: $regex against an array holding no strings, and
$not holding a bare regex.
@LautaroPetaccio
LautaroPetaccio force-pushed the tests/mongo-heuristics-semantics-gaps branch from 0d9344d to 02c4534 Compare September 14, 2026 18:40
@jgaleotti
jgaleotti merged commit 69c947a into fix_all_semantics Sep 16, 2026
31 checks passed
@jgaleotti
jgaleotti deleted the tests/mongo-heuristics-semantics-gaps branch September 16, 2026 18:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants