Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implements lowBoundary and highBoundary #229

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

Diferti
Copy link

@Diferti Diferti commented Apr 16, 2024

This pull request implements lowBoundary and highBoundary as functions on userInvocationTable

The FHIRPath spec says that lowBoundary and highBoundary should work with decimal, date, datetime, and time. To come up with idea how keep picoseconds in Javascript was fun.

To implement this, we need to pass a FHIR model to fhirpath.evaluate. If we do not, we will not have TypeInfo to determine dateTime and date because they overlap when using string checking.

I imported R4 model to use in the reference implementation to do this.

@Yngwarr Yngwarr self-assigned this Apr 22, 2024
Copy link
Collaborator

@Yngwarr Yngwarr left a comment

Choose a reason for hiding this comment

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

Hello! Great work on implementing boundary functions and adding tests! We'll have to take a closer look at TypeInfo and figure out, why it behaves as it is.


// @note this is not exported by fhirpath/src/types but should be
let dateRE = new RegExp(
'^[0-9][0-9][0-9][0-9](-[0-9][0-9](-[0-9][0-9])?)?$');
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's better to use FP_Date.checkString for this.

There are also checkString functions for FP_DateTime and FP_Time.

Copy link
Author

Choose a reason for hiding this comment

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

@Yngwarr I have updated the pull request to use a model with fhirpath.evaluate to make this much easier.

Now we get TypeInfo correctly with dateTime, date, and time.

@@ -1,4 +1,6 @@
import { default as fhirpath } from 'fhirpath'
import fhir_r4_model from 'fhirpath/fhir-context/r4'
import { FP_DateTime, FP_Time } from 'fhirpath/src/types';
Copy link
Author

Choose a reason for hiding this comment

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

Note: these are not exported, but could be

@@ -72,7 +181,7 @@ function process_constants(constants) {
}

export function fhirpath_evaluate(data, path, constants = []) {
return fhirpath.evaluate(data, rewrite_path(path), process_constants(constants), null, fhirpath_options);
return fhirpath.evaluate(data, rewrite_path(path), process_constants(constants), fhir_r4_model, fhirpath_options);
Copy link
Author

Choose a reason for hiding this comment

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

Note: if we don't use model, TypeInfo for Resources will not work.

Question: should we use R4 in reference?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess we can. Do we need it to tell date and dateTime apart?

Copy link
Author

Choose a reason for hiding this comment

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

Yes, to determine date and dateTime, it is important to use the model

@Diferti Diferti changed the title [WIP] Implements lowBoundary and highBoundary Implements lowBoundary and highBoundary May 3, 2024
@Diferti Diferti requested a review from Yngwarr May 3, 2024 23:49
}
if (!day) {
if (month == "02") {
(year % 4) ? day = '28' : day = '29';
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's a bit more complicated with leap years: years that are divisible by 100 are not leap unless they're also divisible by 400 (see. wikipedia). I'm not sure it's that important in our case, but better safe than sorry.

Copy link
Author

Choose a reason for hiding this comment

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

I know this about leap years. I just thought it is not necessary. Thank you for feedback, i will change condition to handle this type of situation.

@@ -72,7 +181,7 @@ function process_constants(constants) {
}

export function fhirpath_evaluate(data, path, constants = []) {
return fhirpath.evaluate(data, rewrite_path(path), process_constants(constants), null, fhirpath_options);
return fhirpath.evaluate(data, rewrite_path(path), process_constants(constants), fhir_r4_model, fhirpath_options);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess we can. Do we need it to tell date and dateTime apart?

@@ -291,7 +357,7 @@
"expect": [
{
"id": "o1",
"decimal": 0.95
Copy link
Author

Choose a reason for hiding this comment

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

If input value is 1.0 then how is it possible to get 0,95? I think it is an error in the test values(same for highBoundary).

},
{
"id": "o26",
"decimal": 1.58700000
Copy link
Author

Choose a reason for hiding this comment

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

JS removes all zeros in the end, so this value looks like 1.587, and lowBoundary will return 1.587, although they are both should be 1.58700000.

},
{
"id": "o33",
"decimal": 15.0809999
Copy link
Author

Choose a reason for hiding this comment

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

This test failed, because the input value was 15.080. However, JS removes 0 in the end of value, so the input becomes 15.08, and the returned value is 15.08999999, but it should be 15.0809999.

Copy link
Collaborator

@johngrimes johngrimes left a comment

Choose a reason for hiding this comment

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

Hi @Diferti, I had a look at your changes, and found a couple of issues relating to the tests being a bit too implementation-specific.

I think if we fix these and merge master back in to this branch, we should be able to finalise this change.

"text": "code"
},
"status": "final",
"valueDateTime": "2010-10-10T15:21"
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is not a valid FHIR dateTime, see: https://hl7.org/fhir/r4/datatypes.html#dateTime

},
"status": "final",
"valueQuantity": {
"value": 123456789123.1234
Copy link
Collaborator

Choose a reason for hiding this comment

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

The result of this test is implementation-specific, what happens if we run this against a runner that can handle higher precision?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry, this is not a test - I mean the tests below that use this resource.

@Diferti Diferti requested a review from johngrimes June 20, 2024 02:09
@johngrimes
Copy link
Collaborator

Digging into this has raised more questions than answers for me - there are multiple versions of the specification and the semantics are not clear to me in any of them.

I've posted a question thread about this in Zulip: https://chat.fhir.org/#narrow/stream/179266-fhirpath/topic/Boundary.20functions

Let's see what the FHIR community comes back with.

@johngrimes johngrimes added this to the v2.0.0 milestone Jun 25, 2024
@johngrimes johngrimes assigned johngrimes and unassigned Yngwarr Jun 26, 2024
@johngrimes johngrimes added the enhancement New feature or request label Jun 26, 2024
@johngrimes
Copy link
Collaborator

I don't actually think that this is necessary to resolve for the spec to go out - it is more of an issue on the reference implementation.

@johngrimes johngrimes removed this from the v2.0.0 milestone Jul 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants