BLQL compares two Int64 values through double
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 82/100
Research direction
Read src/BLite.Core/Query/Blql/BsonValueComparer.cs, especially Compare and its numeric conversion paths. Use the repro values in the issue to verify integer comparisons around 2^53 and long.MaxValue, then run the DynamicCollection oracle tests in tests/BLite.Tests/Oracles/DynamicDifferentialTests.cs. Done when those cases compare integers exactly and the oracle rows pass.
Written by the indexing model from the issue text.
Description
BLQL compares two Int64 (or Int32 and Int64) values by converting both to double, so it cannot tell apart integers above 2^53 that differ by less than their double spacing: {t: {$gt: long.MaxValue - 1}} does not match long.MaxValue, and {t: 2^53} matches 2^53 + 1. The comparer's own summary says integers are compared exactly.
Found by the DynamicCollection oracle tests (tests/BLite.Tests/Oracles/DynamicDifferentialTests.cs, #272), which carry the affected rows (4: indexed/blql and plain/blql, both oracles, total > long.MaxValue - 1: expected the one document with long.MaxValue, got none) as a known candidate until this is fixed.
Repro
// t: long.MaxValue ("max"), long.MaxValue - 1 ("max-1"), 2^53 + 1 ("2^53+1"), all stored as Int64
col.Query(BlqlFilter.Gt("t", long.MaxValue - 1)).ToList(); // expected [max], actual []
col.Query(BlqlFilter.Eq("t", long.MaxValue - 1)).ToList(); // expected [max-1], actual [max, max-1]
col.Query(BlqlFilter.Eq("t", 1L << 53)).ToList(); // expected [], actual [2^53+1]
Expected: exact comparison of integers, as BsonValueComparer's summary says: "Within the same numerical family, values are compared numerically: exactly (as decimal) when neither side is a Double, through double otherwise" (src/BLite.Core/Query/Blql/BsonValueComparer.cs:11-12). LINQ and the typed collection compare long exactly.
Actual: see above. The indexed collection is wrong too: its scan bounds are exact (IndexKey(long)), and the residual filter then drops the right document.
Mechanism (verified on 0450b97)
BsonValueComparer.Compare takes the exact path only when one side is a Decimal128 (BsonValueComparer.cs:29-33); Int32 and Int64 pairs fall through to ToDouble(a).CompareTo(ToDouble(b)) (:35), which rounds above 2^53.
Affected versions: since BLQL (a86d458, v1.9.0). Reproduced on v5.2.3 / 0450b97.
Fix considerations
- Compare as
decimal(orlong) whenever neither side is a Double, as the summary describes: the condition at:31drops theDecimal128requirement. - A Double against an Int64 still goes through
double; comparing those exactly (as MongoDB does) is a further step and not what the summary promises. - The evaluator's cross-type range matching (#267) is in
CompareFilter, a separate fix.
Related: #150 and #222 (closed, the typed decimal and cross-type bound fixes), and the other BLQL rows of the same tests: #264, #265, #266, #267.
- Dominant language
- C#
- Stars
- 66
- Forks
- 6
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 43
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from EntglDb/BLite
-
bug package/generator triage
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
GdprMode.Strict warns that deleted documents are not zeroed, but every delete zero-fills themPossibly taken A pull request linked to this issue is open or already merged. Openbug gdpr package/core triage
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
Maintainers usually reply within 1 day
-
QueryIndexAsync rejects a DateTime boundPossibly taken @CaffeinatedCoder claimed this 1 day ago. Openarea/indexing bug package/core triage
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
EntglDb/BLite#270 · 1 comment ·
Maintainers usually reply within 1 day
-
Collection-per-file mode: creating a collection can route another collection's page to the main file (lock-free read of a Dictionary)Possibly taken @CaffeinatedCoder claimed this 1 day ago. Openbug package/core severity/medium triage
Difficulty 4/5 3-5 days Newbie friendliness 58/100
EntglDb/BLite#312 · 1 comment ·
Maintainers usually reply within 1 day
-
A checkpoint drops a page image committed while it drains the WAL index: the commit is lost and an id can return another documentPossibly taken @CaffeinatedCoder claimed this 1 day ago. Openbug package/core severity/critical triage
Difficulty 4/5 3-5 days Newbie friendliness 35/100
Maintainers usually reply within 1 day
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
qew21/Genshin-Subtitles#45 ·
-
bug priority: P2
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
space-wizards/RobustToolbox#7158 ·
Maintainers usually reply within 1 day
-
:watch: Not Triaged dotnet-csharp/svc fundamentals/subsvc
Difficulty 1/5 Under an hour Newbie friendliness 88/100
Maintainers usually reply within 1 day
-
Wrong values of Kernel32.FileShare.Delete and Kernel32.FileAttributes.PosixSemanticsPossibly taken @ElectLive claimed this today. Openbug good first issue help wanted
Difficulty 1/5 Under an hour Newbie friendliness 83/100
ForNeVeR/TruePath#241 · 1 comment ·
Maintainers usually reply within 1 day