Skip to content

Fix Exp/Ln/Log to return null on non-representable results (#1716)#1804

Open
c-schuler wants to merge 3 commits into
mainfrom
fix/exp-ln-overflow-null
Open

Fix Exp/Ln/Log to return null on non-representable results (#1716)#1804
c-schuler wants to merge 3 commits into
mainfrom
fix/exp-ln-overflow-null

Conversation

@c-schuler

Copy link
Copy Markdown
Contributor

Problem

Exp(1000) and Ln(0) threw exceptions instead of returning null. The CQL spec is explicit for all three operators:

"If the result of the operation cannot be represented, the result is null."

  • Exp(1000) = e¹⁰⁰⁰ = ∞ -> BigDecimal(Double.POSITIVE_INFINITY) threw NumberFormatException, re-wrapped as UndefinedResult.
  • Ln(0) = −∞ -> threw UndefinedResult (while Ln(-1) already returned null - internally inconsistent).
  • Log(0, b) / Log(neg, b) -> uncaught NumberFormatException (no guard at all).

Fix

Replaced the exception-based handling with an explicit isInfinite() / isNaN() check that returns null when the result can't be represented as a Decimal. This also removes the UndefinedResult machinery (net-negative lines) and closes the Log gap.

  • Exp(1000) -> null
  • Ln(0) -> null, Ln(-1) -> null (now consistent)
  • Log(0, 2) -> null

Tests

Un-doctored the vendored engine-fhir copy of CqlArithmeticFunctionsTest.xml - these had been marked invalid="true" to match the old throwing behavior:

Test Expression Before After
Exp1000 Exp(1000) invalid null
Exp1000D Exp(1000.0) invalid null
Ln0 Ln(0) invalid null
LnNeg0 Ln(-0) invalid null

Validated: spotlessApply, :engine:detekt, full :engine:jvmTest, full :engine-fhir:test - all green.

Upstream follow-up

The canonical cql-tests (https://github.com/cqframework/cql-tests) suite still marks Exp1000 and Ln0 as invalid="true", which now contradicts the explicit spec clause above. A companion PR to cql-tests is needed to change these to expect null; until then the conformance dashboard will report them as failing.

Fixes #1716.

@c-schuler c-schuler self-assigned this Jul 8, 2026
@c-schuler c-schuler added the bug label Jul 8, 2026
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

Related Issues

The following open issues may be related to this PR:

Issue Title Score Matched Terms
#1733 Operation Predecessor DateTime and Time underflow does not return null 40.5 "result null", "cql tests", "represented result", "result operation", "cannot represented", "operation cannot", "return null", "invalid true", result, xml, true, return, expect, represented, invalid, operation, null, expression, https, cannot, tests, representable, fhirpath (path), org (path), cql (path), hl7 (path), test (path)
#1734 Operation Predecessor DateTime and Time overflow does not return null 39 "result null", "cql tests", "represented result", "result operation", "cannot represented", "operation cannot", "return null", "invalid true", result, true, return, represented, above, invalid, operation, null, expression, https, cannot, tests, representable, org (path), cql (path), hl7 (path), test (path)
#1400 patientBirthDatePropertyName marked as deprecated but still required for SystemFunctionResolver 33.5 "com cqframework", "cql spec", "https github", "github com", "cqframework cql", non, clause, instead, cqframework, github, com, marked, expect, problem, behavior, spec, null, https, returned, cannot, src (path), functions (path), main (path), org (path), cql (path), elm (path), hl7 (path)
#1377 Use a git module for the XML-based tests 31.5 "com cqframework", "cql tests", "fhir test", "https github", "github com", "engine fhir", "cqframework cql", xml, cqframework, github, com, fhir, https, suite, based, tests, engine (path), cql (path), test (path)
#1794 Point from Interval[null, null] is returning null instead of erroring 30.5 "null result", "instead returning", "invalid true", "null null", "returning null", result, xml, true, instead, return, returning, operators, invalid, spec, null, expression, https, tests, fhirpath (path), org (path), cql (path), hl7 (path), test (path)

Tip: If this PR addresses any of these issues, please link them using Closes #NNN or Refs #NNN in the PR description.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

Formatting check succeeded!

@codecov

codecov Bot commented Jul 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 33.33333% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.76%. Comparing base (95366e9) to head (80e0b41).

Files with missing lines Patch % Lines
...encds/cqf/cql/engine/elm/executing/ExpEvaluator.kt 0.00% 4 Missing ⚠️
...pencds/cqf/cql/engine/elm/executing/LnEvaluator.kt 50.00% 1 Missing and 1 partial ⚠️
...encds/cqf/cql/engine/elm/executing/LogEvaluator.kt 50.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##               main    #1804   +/-   ##
=========================================
  Coverage     68.75%   68.76%           
  Complexity     1699     1699           
=========================================
  Files           536      536           
  Lines         30559    30555    -4     
  Branches       7013     7012    -1     
=========================================
- Hits          21011    21010    -1     
+ Misses         6994     6989    -5     
- Partials       2554     2556    +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sonarqubecloud

sonarqubecloud Bot commented Jul 9, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Evaluation of EXP(1000) and Ln(0) operations does not return null

3 participants