Repository navigation
Conversation
Loki's MergeBinOp returns NaN for a zero right operand of / and % whatever the numerator is, for literal folds, vector against literal and vector against vector. The proxy computed IEEE a/b, so 1 / 0 and sum(rate(...)) / 0 were +Inf or -Inf, and the fallback arithmetic answered 0.
⚪ Performance A/B: no change beyond noise8 shape×range — 8 ⚪ same · results vs Loki: 7 same, 0 new difference(s), 1 pre-existing Every shape is within noise of the base build (±30% and 100 ms). 8 unchanged shape×range (within noise)
Cold (first-run) timings — what a user opening a panel sees
Why these shapes
base |
✅ Visual smoke: passed with warningsBase
Gate: a base-vs-PR data difference passes when the PR is closer to Loki, and fails when the PR diverges from Loki or Loki cannot decide it (at a range Loki does not hold, a difference passes when the same page proved it closer to Loki at a shorter range; otherwise label the pull request dd-fields-1h: history-dependent difference, not gated (1): resource /api/datasources/uid/*/resources/patterns?end=2026-10-12T12%3A36%3
dd-service-logs-1h: history-dependent difference, not gated (1): resource /api/datasources/uid/*/resources/patterns?end=2026-10-12T12%3A36%3
All montages of this run: |
PR Quality ReportCompared against base branch Coverage and tests
Compatibility
Performance smokeLower CPU cost (
State
|
PR Quality ReportCompared against base branch Coverage and tests
Compatibility
Performance smokeLower CPU cost (
State
|
…he compose Loki times out on literal-only queries





Summary
New gap:
semantics/binary-division-by-zero-nan.Loki's rule. In Loki 3.7.7,
syntax.MergeBinOp(pkg/logql/syntax/ast.go:1978-2005) returns NaN for a zero right operand of/and%, whatever the numerator. This applies:reduceBinOpatast.go:1918, so1 / 0is NaN;LiteralStepEvaluator:evaluator.go:1179;vectorBinop:evaluator.go:1020.What the proxy did.
binarySampleValuecomputeda / b, sox / 0,-1 / 0andInf / 0gave ±Inf. Only0 / 0gave NaN.applyOpreturned 0 for both/and%.Fix. Both now return NaN for
/and%when the divisor is 0 or -0. Comparisons (with and withoutbool),^, and NaN/Inf operands already matchedMergeBinOp; the edge table now pins them.Tests
TestBinarySampleValueMatchesLokiMergeBinOp: 12 operators × 9 operands squared (0, -0, ±1, 2.5, -7, NaN, ±Inf), with and withoutbool, against a direct port ofMergeBinOp.TestBinaryMatchersMatchLokiMergeBinOp: the same table through the scalar-right, scalar-left and vector-vector matchers.TestBinaryScalarFoldMatchesLokiReduceBinOp.TestApplyOpDivisionAndModuloByZeroAreNaN.TestBinaryVectorDivisionByZeroHandlers: query_range and query.TestBinaryConstantVectorDivisionByZeroInstant.TestCompat_BinaryDivisionByZeroIsNaN, 12 shapes on query and query_range.Pending before ready
1/0NaN; drop the duplicate test row.