-
Type:
Task
-
Resolution: Unresolved
-
Priority:
Major - P3
-
None
-
Affects Version/s: None
-
Component/s: None
-
None
-
Query Execution
-
None
-
None
-
None
-
None
-
None
-
None
-
None
$expr can be used inside a find query to evaluate its filter. MatchExpressionEvaluator stores an EvaluationContext and forwards it to Expression::evaluate() when it visits an ExprMatchExpression node. We should make sure that classic find layer that might use an $expr supplies a non-empty EvaluationContext. When there is a filter in the find layer the stage Filter is used . This is called by six stages CollectionScan, IndexScan, Fetch, Or, TextOr, and MultiRangeClusteredScan. All of them need to pass an EvaluationContext to Filter::passes to be threaded to exec::matcher::matches().
The same gap exists on the write path: write_stage_common::ensureStillMatches() re-checks a fetched document against the query predicate after a yield, calling exec::matcher::matchesBSON() with no EvaluationContext. It's used by UpdateStage, DeleteStage, BatchedDeleteStage (which inherits DeleteStage's tracker), and TimeseriesModifyStage . All need an EvaluationContext threaded through.
Two aggregation exec stages have the same problem independently of MatchStage, since they call exec::matcher::matchesBSON() directly against a user-supplied filter rather than going through MatchProcessor:
- ChangeStreamUnwindTransactionStage evaluates a user filter per operation inside a transaction (TransactionOpIterator's hot loop).
- InternalUnpackBucketStage evaluates a whole-bucket filter per bucket and an event filter per unpacked measurement.
Where a stage already has a memory tracker/knob for something else (e.g. IndexScan, Or, TextOr for dedup/scoring; UpdateStage for its existing limit), reuse it instead of adding a second one. Otherwise, create a new tracker via OperationMemoryUsageTracker::createChunkedSimpleMemoryUsageTrackerForStage() with a dedicated knob.
Two other candidates were checked and ruled out: $pull's condition matcher and partial index filters both ban $expr at parse time (MatchExpressionParser::kBanAllSpecialFeatures), so no tracking is needed there.