Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

BLQL compares two Int64 values through double

オープン 初心者向け
#268 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
82/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
csharp
領域
backend, databases

調査の方向性

src/BLite.Core/Query/Blql/BsonValueComparer.cs、特に Compare と数値変換の経路を読む。issue の再現値を使って、2^53 および long.MaxValue 付近の整数比較を検証し、その後 tests/BLite.Tests/Oracles/DynamicDifferentialTests.cs の DynamicCollection oracle テストを実行する。これらのケースで整数が正確に比較され、oracle の行がパスすれば完了。

索引モデルが issue の本文から書いたものです。

説明

area/linq bug package/core triage

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, PR to follow, stacked on #263), 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 (or long) whenever neither side is a Double, as the summary describes: the condition at :31 drops the Decimal128 requirement.
  • 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.

主要言語
C#
スター
66
フォーク
6
平均マージ
1日 2時間
マージ済み PR(30日)
43

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

EntglDb/BLite のほかの issue

EntglDb/BLite の issue をすべて見る

似ている issue

C# の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。