You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Index range with a constant of another type than the property (r.Count < 9.5, r.Count >= 5L) selects the wrong keys #222
IndexOptimizer.ParseSimplePredicate keeps the type of the constant in a comparison instead of converting it to the type of the indexed property. Index keys carry no type tag and are compared bytewise, so a bound of another type (double or long against an int index, double against a long index, ...) is encoded as a different key layout and selects the wrong range.
Repro
Reading with an indexed int Count, 20 documents with Count = 0..19:
Query
LINQ to Objects
BLite
Count(r => r.Count < 9.5)
10
20
Where(r => r.Count >= 5L).ToList()
15 rows
20 rows
Where(r => r.Count <= 5L).Max(r => r.Count)
5
throws
Where(r => r.Count >= 2.5).ToList()
17 rows
0 rows
Strict operators that end up as StrictBoundary are post-filtered, so some of these shapes come out right by luck; inclusive bounds and the Count(predicate) push-down (CountByPredicateAsync) are not.
Where
IndexOptimizer.ParseSimplePredicate (src/BLite.Core/Query/IndexOptimizer.cs): MinValue/MaxValue keep the constant's runtime type.
ConvertToIndexKey then encodes that value as is.
Suggested fix
Convert the bound to the property's type when the conversion is exact. Otherwise adjust it: Count < 9.5 becomes Count <= 9, Count >= 2.5 becomes Count >= 3, and a bound outside the property's range makes the predicate always true or always false. If none of that applies, give up on the index (no plan). Add the queries above as tests, for typed collections and for DynamicCollection.
Found while re-reviewing #183. That PR now refuses such bounds on its index-key aggregate path, so it does not make this worse.
Activity
fix(index): express comparison bounds in the indexed property's type (#…