-
Type: Improvement
-
Resolution: Unresolved
-
Priority: Major - P3
-
None
-
Affects Version/s: None
-
Component/s: None
-
Labels:None
-
Query Execution
When we generate an SBE plan for a simple query like find({a:1}), the filter includes a fillEmpty operation beneath the traverseF's lambda:
> db.c.find({a: 1}).explain().queryPlanner.winningPlan.slotBasedPlan.stages [1] filter {traverseF(s1, lambda(l101.0) { ((move(l101.0) == s4) ?: false) }, false)} [1] scan s2 s3 none none none none none none
The traverseF instruction will actually treat Nothing values as false, so the fillEmpty (expressed in the plan using ?: ) can be removed in this case, probably in the type checking phase.
We should also consider whether we can remove fillEmptys from lambdas within an elemMatch? E.g.
> db.c.find({a: {$elemMatch: {$gt: 1, $lt: 5}}}).explain().queryPlanner.winningPlan.slotBasedPlan.stages [1] filter {((isArray(s1) && traverseF(s1, lambda(l101.0) { (((l101.0 < s4) ?: false) && ((l101.0 > s5) ?: false)) }, false)) ?: false)} [1] scan s2 s3 none none none none none none lowPriority [s1 = a] @"17d5a82e-6d15-47cc-8cfd-107fe6dc2213" true false
Does this need both fillEmpty's, or can we rely on the AND propagating Nothing, followed by traverseF treating it as false? This is something that should also be investigated.