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
Select followed by Any / Count(predicate) / Max / Sum returns false or 0: value-type default is taken as the push-down result #181
Version: BLite 5.2.1 (main at 45dbc8c), .NET 10.0.12, macOS 27 arm64 (the code path is platform-independent)
What happens
A LINQ query that ends in a Select followed by a terminal returning a value type (bool, int, long, decimal, ...) silently returns that type's default. Select(p => p.Age).Any() returns false and Select(p => p.Age).Max() returns 0 on a collection full of matching documents. No exception is thrown.
varpushed=TryPushDownSelect<TResult>(model.SelectClause,model.WhereClause);if(pushedis not null)returnpushed;
TryPushDownSelect only applies to sequence results. For anything else it returns default to mean "not applicable" (BTreeQueryProvider.cs:599-605):
if(!resultType.IsGenericType)returndefault;
For a reference-type result such as string, default is null, so First() falls through and works. For a value-type result, TResult? on an unconstrained generic is just TResult. So default is false or 0, which is not null, and the caller returns it as the query result.
Count() is unaffected only because an earlier fast path handles it. Where(...).Select(...).Any() has the same problem.
Repro
Runs as-is in tests/BLite.Tests against the existing TestDbContext (PeopleV2).
Only try the push-down when TResult is a sequence, or have TryPushDownSelect report success with a bool and an out value instead of using default as a sentinel. Any other early-return helper that uses default to mean "not applicable" would have the same problem for value-type results; I haven't checked them all.
Happy to send a PR for this if you would like one.
Confirmed on main: Select(p => p.Age).Any(), .Any(pred), .Count(pred) and .First(), and Where(...).Select(...).Any(), return false or 0. Element terminals after a Select go through TryPushDownSelect (BTreeQueryProvider.cs ~L287-294), which ignores HasComplexOperators and returns default. A PR would be welcome. Please coordinate with #180, which touches the same terminal handling.
Activity
mrdevrobot commentedon Oct 12, 2026
Confirmed on
main:Select(p => p.Age).Any(),.Any(pred),.Count(pred)and.First(), andWhere(...).Select(...).Any(), return false or 0. Element terminals after aSelectgo throughTryPushDownSelect(BTreeQueryProvider.cs~L287-294), which ignoresHasComplexOperatorsand returnsdefault. A PR would be welcome. Please coordinate with #180, which touches the same terminal handling.fix(query): do not replay the index window when the root is used agai…
fix(query): keep lambdas inline when EnumerableRewriter replays a que…
fix(query): replay over the whole collection when a query reads a sec…
fix(query): return the real result of terminals after Select and afte…