Skip to content

CQL Long#363

Open
cmoesel wants to merge 4 commits into
masterfrom
cql-long
Open

CQL Long#363
cmoesel wants to merge 4 commits into
masterfrom
cql-long

Conversation

@cmoesel
Copy link
Copy Markdown
Member

@cmoesel cmoesel commented May 11, 2026

This PR introduces support for CQL Long, represented using BigInt in JavaScript. Since Integer and Decimal are represented using Number, we can easily distinguish CQL Longs from Integers and Decimals by their type (typeof var === 'bigint'). This actually made implementation easier (and more correct) compared to my initial implementation using Number (which I thought would be easier since it was more of an incremental change, but maybe not).

You can test this by building and running a CQL library that uses Long types -- or you can just review the unit tests and trust that they are properly exercising the capability.

Submitter:

  • This pull request describes why these changes were made
  • Code diff has been done and been reviewed (it does not contain: additional white space, not applicable code changes, debug statements, etc.)
  • Tests are included and test edge cases
  • Tests have been run locally and pass
  • Code coverage has not gone down and all code touched or added is covered.
  • Code passes lint and prettier (hint: use npm run test:plus to run tests, lint, and prettier)
  • All dependent libraries are appropriately updated or have a corresponding PR related to this change (N/A)
  • cql4browsers.js built with npm run build:browserify if source changed.

Reviewer:

Name:

  • Code is maintainable and reusable, reuses existing code and infrastructure where appropriate, and accomplishes the task’s purpose
  • The tests appropriately test the new code, including edge cases
  • You have tried to break the code

@cmoesel cmoesel mentioned this pull request May 11, 2026
11 tasks
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 11, 2026

Codecov Report

❌ Patch coverage is 75.82418% with 22 lines in your changes missing coverage. Please review.
✅ Project coverage is 87.87%. Comparing base (d1b1b14) to head (f1106c2).

Files with missing lines Patch % Lines
src/util/math.ts 68.75% 8 Missing and 2 partials ⚠️
src/elm/type.ts 75.86% 5 Missing and 2 partials ⚠️
src/runtime/context.ts 0.00% 2 Missing and 1 partial ⚠️
src/elm/arithmetic.ts 91.66% 0 Missing and 1 partial ⚠️
src/elm/literal.ts 83.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #363      +/-   ##
==========================================
+ Coverage   87.58%   87.87%   +0.28%     
==========================================
  Files          52       53       +1     
  Lines        4606     4683      +77     
  Branches     1297     1301       +4     
==========================================
+ Hits         4034     4115      +81     
- Misses        359      373      +14     
+ Partials      213      195      -18     

☔ View full report in Codecov by Sentry.
📢 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.

@cmoesel cmoesel marked this pull request as draft May 11, 2026 13:53
@cmoesel cmoesel marked this pull request as ready for review May 11, 2026 15:26
cmoesel added 3 commits May 11, 2026 14:38
- Add support for Long literal, ToLong conversion, min/max long values
- Use JavaScript Number to represent Long (NOTE: this means that values are imprecise outside of the safe integer range in JS)
- Add tests for literals, conversion, and other operations that accept Long arguments
- Improve underflow/overflow tests to test boundaries more carefully
- Added .skip to tests that fail due to Number imprecision for high values
- Unskipped Long tests in the spec tests that now pass
Update support for Long to use BigInt so we can distinguish between decimal/integer (JS Number) and long (JS BigInt).
- support for <, <=, >=, > for long/bigint types
- support for ConvertsToLong and Convert operator with Long
Copy link
Copy Markdown
Contributor

@lmd59 lmd59 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good! The tests are very thorough and helpful for confirming successful implementation. I left a couple of small comments on tests. Most are just nitpick/optional, but I think a couple more aggregate tests wouldn't hurt.

I also wanted to ask about support for Long in the interval datatype
https://cql.hl7.org/04-logicalspecification.html#interval states that "An interval must be defined using a point type that supports comparison, as well as Successor and Predecessor operations, and Minimum and Maximum Value operations." Long seems like it would fit in this category. Is there any reason not to support Long as part of an interval?

(await this.intOne.exec(this.ctx)).should.equal(1);
});

it('should convert 1L to 1', function () {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this be a little more clear?

Suggested change
it('should convert 1L to 1', function () {
it('should convert 1L to 1n', function () {

this.longOne.value.should.equal(1n);
});

it('should execute 1L as 1', async function () {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this be a little more clear?

Suggested change
it('should execute 1L as 1', async function () {
it('should execute 1L as 1n', async function () {

define LongDivideUnderflow: minimum Long / 0.5
define LongDivideNearOverflow: ToLong(maximum Integer) / 1L
define LongDivideNearUnderflow: ToLong(minimum Integer) / 1L
define LongDivideByZero: 1L / 0L
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it add anything to consider a long/integer mixed divide by zero?

// @Test: Product
define decimal_product: Product({1.0, 2.0, 3.0, 4.0})
define integer_product: Product({5, 4, 5})
define long_product: Product({5L, 4L, 5L})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recommend adding a test for over/underflow on an aggregate product.


// @Test: Sum
define not_null: Sum({1,2,3,4,5})
define longs: Sum({1L,2L,3L,4L,5L})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good test for aggregate functionality. Would also recommend adding a test for over/underflow on an aggregate sum.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants