Skip to content

Clarify Start and End operators when boundaries are null#104

Merged
brynrhodes merged 6 commits into
masterfrom
start-end-null
Jun 25, 2026
Merged

Clarify Start and End operators when boundaries are null#104
brynrhodes merged 6 commits into
masterfrom
start-end-null

Conversation

@cmoesel

@cmoesel cmoesel commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

The CQL specification already indicates that open null boundaries represent uncertainties of specific ranges.

From the Author's Guide:

If a boundary point is null and the boundary is exclusive, the boundary is considered unknown, and represents an uncertainty between the boundary and the minimum or maximum value for the point type of the interval.

From the Logical Specification:

If the low bound of the interval is null and open, the low bound of the interval is interpreted as unknown and represented as an uncertainty from the minimum value for the point type to the high boundary (inclusive); computations involving the low boundary may result in null.

...

If the high bound of the interval is null and open, the high bound of the interval is unknown and represented as an uncertainty from the low boundary (inclusive) to the maximum value for the point type; computations involving the high boundary may result in null.

The current definitions of Start and End, however, lose this nuance, as they state:

If the [low|high] boundary of the interval is open... [and] the low value of the interval is null, the result is null.

This PR updates the Start and End definitions to align more closely to the existing Interval definitions that indicate open null boundaries are uncertainties.

Relevant changes in the definition for Start:

If the low boundary of the interval is closed and non-null, this operator returns the low value of the interval. If the low boundary of the interval is closed and null, this operator returns the minimum value for the point type of the interval.

If the low boundary of the interval is open and non-null, this operator returns the successor of the low value of the interval. If the low boundary of the interval is open and null, this operator returns an uncertainty from the minimum value for the point type of the interval to the high boundary of the interval (using End operator semantics to determine the high boundary).

If the low boundary is null and the interval point type is unknown, a choice of types, or Any, then the result cannot be determined and this operator returns null.

Relevant changes in the definition for End:

If the high boundary of the interval is closed and non-null, this operator returns the high value of the interval. If the high boundary of the interval is closed and null, this operator returns the maximum value for the point type of the interval.

If the high boundary of the interval is open and non-null, this operator returns the predecessor of the high value of the interval. If the high boundary of the interval is open and null, this operator returns an uncertainty from the low boundary of the interval (using Start operator semantics to determine the low boundary) to the maximum value for the point type of the interval.

If the high boundary is null and the interval point type is unknown, a choice of types, or Any, then the result cannot be determined and this operator returns null.

By updating these definitions, all Interval operators that describe their calculations using start and end arrive at more correct results. For example, Interval[null, 0] includes Interval(null, 0] results in null according to a strict reading of the existing Include, Start, and End definitions; but it correctly results in true when these new Start and End definitions are applied.

Relevant examples have also been added to the CQL Reference to demonstrate how the definitions are applied.

I've also clarified the language in the Interval definition within the logical specification to avoid possible misinterpretations of the term high boundary (inclusive). In short, I updated the definition to use the terms low bound and high bound consistently and to cross-reference each other (e.g., ... represented as an uncertainty from the low bound (see above)... and ... to the high bound (see below)...).

An alternate (or additional) approach to fixing the interval operator definitions would be to update every operation (Include, Before, After, etc.) to specifically indicate how it behaves with open and closed null boundaries. This is not necessary, however, if we update the Start and End definitions since all of these operations are defined in terms of Start and End.

cmoesel added 2 commits June 17, 2026 15:11
* Make .sh files executable
* Run _updatePublisher.sh to update scripts
The specification already indicates that open null boundaries represent uncertainties of specific ranges (based on the point type and other boundary of the interval). Update the `Start` and `End` operators to align with this approach. This impacts how many of the interval operators are calculated, causing results to be more correct.

@lmd59 lmd59 left a comment

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.

Big fan of this update! I just left a comment (well 3 related comments) with a suggestion that I suspect is not at all necessary but an idea for consideration.

One question that I have that is related but may be out of scope:
The logical specification makes it clear that the uncertainty created from a null open bound is inclusive. Does this potentially create an odd situation when the other boundary is open?
For instance, (null, 5), I would interpret to mean an interval that ranges from uncertainty[-2147483648, 5] to 4. The low boundary of the interval has an uncertainty that could be higher than the high boundary!
Should we potentially also suggest an update to the definition of Interval (https://cql.hl7.org/04-logicalspecification.html#interval) to make this case clearer?

Comment thread input/pages/04-logicalspecification.md Outdated
Comment thread input/pages/04-logicalspecification.md Outdated
@cmoesel

cmoesel commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

One question that I have that is related but may be out of scope: The logical specification makes it clear that the uncertainty created from a null open bound is inclusive. Does this potentially create an odd situation when the other boundary is open? For instance, (null, 5), I would interpret to mean an interval that ranges from uncertainty[-2147483648, 5] to 4. The low boundary of the interval has an uncertainty that could be higher than the high boundary!

I think this depends on how you interpret high boundary. I interpret it using the semantics of the End operator. The high value is 5 (because interval.high is 5 regardless of the interval.highClosed value), but high boundary might be 4. That said, I do agree that high boundary is ambiguous and others (like you!) might interpret it another way. This is why I chose to use the word end in my definitions, which is explicitly defined -- but based on your other comments, I guess that didn't quite hit the mark either.

@lmd59 lmd59 left a comment

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.

Thank you for the thoughtful responses! Based on those, it might also be helpful to add one more case to each set of cql reference examples that shows the expected outcomes for a fully open interval where one of the values is null. Suggested updates inline, also fixes a small typo!

Comment thread input/pages/09-b-cqlreference.md Outdated
Comment thread input/pages/09-b-cqlreference.md Outdated

@lmd59 lmd59 left a comment

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.

Small typo. Otherwise looks good!

Comment thread input/images/elm/schema/expression.xsd Outdated
Comment thread input/pages/04-logicalspecification.md Outdated
Comment thread input/pages/09-b-cqlreference.md Outdated
Co-authored-by: lmd59 <lmd59@cornell.edu>

@lmd59 lmd59 left a comment

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.

Nice update!

@cmoesel cmoesel marked this pull request as ready for review June 19, 2026 19:38

@brynrhodes brynrhodes left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks really good, just a minor nitpick with some of the language that refers to null "values" (no such thing, null is not a value)

Comment thread input/pages/09-b-cqlreference.md Outdated
Comment thread input/pages/09-b-cqlreference.md Outdated
Comment thread input/pages/09-b-cqlreference.md Outdated
Comment thread input/pages/09-b-cqlreference.md Outdated
Comment thread input/pages/09-b-cqlreference.md Outdated
Comment thread input/pages/09-b-cqlreference.md Outdated
Comment thread input/pages/09-b-cqlreference.md Outdated
Comment thread input/pages/09-b-cqlreference.md Outdated
Comment thread input/pages/09-b-cqlreference.md Outdated
Comment thread input/pages/09-b-cqlreference.md Outdated
Co-authored-by: Bryn Rhodes <brynrhodes@users.noreply.github.com>
@cmoesel

cmoesel commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review, @brynrhodes. I've accepted all of your edits! Let me know if there is anything else you think we should adjust.

Also, I forgot to note in the description, but I updated the IG Publisher scripts too. Technically, only the _build scripts are maintained by HL7 now, but I kept the others as well in case there is CI or other tools expecting them to be there.

@brynrhodes brynrhodes merged commit 7dcbae4 into master Jun 25, 2026
@brynrhodes brynrhodes deleted the start-end-null branch June 25, 2026 04:12
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