Closed jackcmeyer closed 7 years ago
This behavior is an unintended consequence of the fix for #115. The problem is that the whole point of profiles was to enable the retrieve to always return the same base type, but to allow the positive or negative aspect of the request to be communicated via the profile used through the data access layer.
What we said in #115 was that we wanted to preserve the profile type for operands to functions, so that only a "positive" encounter performed could be passed to a function that expected a "positive" encounter performed. The unintended consequence is that since the retrieve is actually returning the base type, it can no longer be passed to the function, because it's not a "positive" encounter performed, at least so far as the compiler knows (because we explicitly set the return type of the retrieve to the base type).
So, we have three choices:
1) Leave it as is, forcing the function to be declared as the base type (which is what the workaround above does).
2) Change the operand behavior to be consistent with the retrieve behavior (i.e. the function will now take an argument of the base type, regardless of the profile used in the declaration).
3) Change the retrieve to return the profile type, rather than the base type.
I think option 1 is a non-starter because it results in surprising and hard to understand behavior.
I think option 3 is reasonable, but it means that the data access layer will be given the derived type, not the base type.
I think option 2 is reasonable as well, but it basically means that profiles are always and only useful in the context of a retrieve.
We agree that option 1 is a non-starter. If we get to pick, we prefer option 3, since on the authoring side, it is easier for comparison of like operands to determine if they are equivalent. It also provides consistency for the author. Option 2 seems to gushy and would pretty much regress what was fixed in #115. However, we realize that this also has an impact on the execution engine, so we wonder if this should be a bigger discussion at some point. For now, I think we just need to decide on something. Thoughts?
I'm not opposed to option 3. @c-schuler any thoughts on the impact of this change on the Java-based engine? @cmoesel thoughts on the JS engine impacts?
I'm not sure I entirely understand the implications of option 3. Could someone maybe provide a real-world example and how that affects what the execution engine has to do?
From the model-info perspective, a profile is a sub-class that is not allowed to extend. It's effectively a marker interface. So the only real impact on the data access layer is that they would be expected to support these derived classes explicitly, instead of just using their names as markers as we were previously doing.
For example:
["Encounter, Performed": "Inpatient"]
The current translator returns this as a list of QDM.EncounterPerformed
, which is the structural base class for both "positive" and "negative" profiles. What we're suggesting with option 3 is that the translator would indicate this is a result of type QDM.PositiveEncounterPerformed
. Structurally, this is the same class, but prior to this change, the data access layer only dealt with this "class" as a name in the retrieve implementation. We'd now be requiring the engine to explicitly support representing the profile classes.
Ah, OK. In that case, I think we'd be OK. In what few data source implementations we have, I think we first look up items by profile name, then if we don't find that, we look up by class name. So I think we'd be fine with this change. In fact, I thought that was how it was supposed to work all along!
I have no qualms with option 3.
Fixed by pull request #141.
Dear, I have similar error when trying the get the data-requirement from my lib :
Could not resolve call to operator today with signature ()
CQL example :
define "EmCareDT01":
difference in years between today() and Patient.BirthDate < 5
do you think it is related ?
When using the CQL file below, the following error occurs
Could not resolve call to operator Hospitalization with Signature (QDM.EncounterPerformed).
In the previous versions of CQL, this was a valid way of making a call to a function.When modifying the above example to the following, no errors occur.
The following ELM is produced