-
Notifications
You must be signed in to change notification settings - Fork 24
CQL Error Messages
As with any language, it is possible to construct statements in CQL that contain errors. The process of validating CQL finds these errors, and authoring environments return errors from this validation process to users to help build correct statements.
It's helpful to think of these messages in the same context as forming a correct sentence in any language. We can do this by considering the kinds of errors that are possible:
- Typographical Errors
- Grammatical Errors
- Errors in Meaning
Typographical errors are things like misplaced punctuation, misspellings of key words, and similar errors. For example:
Thx ;qikc r3dd fawks jump#d ov8r th3 lazy; br"oiw d@huwg
In human communication, these types of errors obscure meaning, but humans can generally get through them. For a machine, however, this is a significant barrier. These types of errors (often called "lexical" errors) are handled by the first phase of validation, which ensures that all the pieces of a statement are well understood.
Grammatical errors occur when sentences misuse categories of words like nouns and verbs, or place words in incorrect order. For example:
Quickly fox red the jumped lazy dog over brown.
The sentence is typographically correct, there are no misspellings or misuse of punctuation, but grammatically, the construction is invalid. In this simple example, the meaning probably still comes through for humans, but as with typographical errors, for a machine this represents a significant barrier. These types of errors (often called "syntax" errors) are handled by the second phase of validation, which ensures that statements are well formed according to the rules of CQL grammar.
The third category of errors occur when sentences are typographically and grammatically correct, but construct sentences that have nonsensical meanings. For example:
Colorless green ideas sleep furiously.
The sentence is grammatically correct, it follows all the rules of the English language, but it is a nonsensical statement. These types of errors (often called "semantic" errors) are handled by the third phase of validation, which ensures, to the extent possible, that the CQL expression is valid. For example:
1 + 'John'
This is typographically and grammatically valid (often called "syntactically" valid) expression of CQL, but semantically, you cannot add numbers and strings together, because the +
operator is not defined for the combination of numbers and strings.
When validating, CQL uses these categories of errors to help inform the author about things that have gone wrong during the process. These categories are referred to as:
- Syntax Errors: Typographical or Grammatical errors
- Semantic Errors: Errors of meaning
When the CQL validator cannot determine what pieces (tokens) a sentence is made up of, you'll receive a Syntax error with a pointer to the position in the expression that cannot be resolved. For example:
asdf;fjkla;oiwejf
Attempting to validate a random string of characters will typically result in an error like this:
Syntax error at asdf
More common errors in this category are things like missing a closing quote (\``) or parenthesis (
)`) symbol:
define "Initial Population": ["Encounter, Performed: "XYZ"]
define "Combination": "Initial Population" and ("First Condition" or "Second Condition"
Would typically give something like:
Syntax error at XYZ
Syntax error at <EOF>
Note the second error, Syntax error at <EOF>
. This is a special marker in the validation step that is used to indicate the End-Of-File, or the end of the input. It's typical of situations where the validator is looking for a closing mark but reaches the end of the input before it finds it.
When the CQL validator encounters expressions of CQL that have no typographical errors, but do not conform to the rules of the language, it will return a Syntax error with information about where the error occurred, and what the validator expected to find. For example:
define "Encounters": ["Encounter, Performed": "XYZ"] where relevantPeriod during "Measurement Period"
This expression is typographically correct, but it is missing a key syntactic element, the alias that introduces the query context. Without the alias, the keyword where
cannot be used, so the validator returns a message:
Syntax error at where
One of the key syntactic elements in CQL is the identifier. Identifiers are used throughout the language to refer to things like data types, value sets, code systems, functions, query sources (via aliases) and expression definitions. If the validator cannot determine what an identifier is referring to, it will return an error indicating what identifier cannot be resolved, and what kind of thing was expected. For example:
define "Encounters": ["Encounter Performed": "XYZ"] E where E.relevantPeriod during "Measurement Period"
This is a syntactically valid expression, but in attempting to validate it, we need to know what the result of the retrieve (["Encounter Performed": "XYZ"]
) is. To do this, the translator looks for a type named Encounter Performed
in the data model being used (Quality Data Model, or QDM, in this case). Note the missing ,
in the name of the data type. This results in the validator not being able to find the type by its appropriate label, and it returns the error:
Could not resolve type name Encounter Performed.
If we correct that:
define "Encounters": ["Encounter, Performed": "XYZ"] E where E.relevantPeriod during "Measurement Period"
The validator then knows what type of data is being returned, and next validates the terminology filter, a reference to XYZ
in this case. For a retrieve to be meaningful, the identifier must be a reference to a terminology item, a value set, code system, or direct reference code, so the validator tries to look up the identifier XYZ
in the list of things it knows about it. Because we haven't defined XYZ
in this library, it returns the error:
Could not resolve identifier XYZ in the current library.
And providing a value set declaration with the name XYZ
solves this problem:
valueset "XYZ": 'urn:oid:1.2.3.4'
This catalog lists the semantic errors that may be encountered when validating CQL. Note that throughout these descriptions, error messages are provided with tokens (%s
) that will be replaced with the appropriate value from the input CQL to help identify the error. For example, in the message:
Could not resolve identifier %s in the current library.
The token %s
will be replaced with the identifier that cannot be found, so that the message you'll actually received from the validator is:
Could not resolve identifier XYZ in the current library.
The catalog is organized into groups of related errors in the sections that follow.
Attempting to use an expression where a literal is required:
Expressions in this context must be able to be evaluated at compile-time.
Attempting to use an invalid UCUM unit:
Unknown UCUM unit
Attempting to use an identifier that is not defined:
Could not resolve identifier %s in the current library.
Could not resolve reference to code %s.
Could not resolve reference to code system %s.
Could not resolve type name %s in model %s.
Attempting to use the same identifier for different definitions in the same library:
Identifier %s is already in use in this library.
Attempting to reference a private component of a library:
Object %s in library %s is marked private and cannot be referenced from another library.
Referencing an expression or other definition that contains unresolved errors:
Could not validate reference to expression %s because its definition contains errors.
Could not validate reference to parameter %s because its definition contains errors.
Could not validate reference to codesystem %s because its definition contains errors.
Could not validate reference to valueset %s because its definition contains errors.
Could not validate reference to code %s because its definition contains errors.
Attempting to use a definition to define itself (i.e. recursively, or circular reference):
Cannot resolve reference to expression or function %s because it results in a circular reference.
Using an unknown property name on an interval:
Invalid interval property name %s.
Using an unknown property name on an object or tuple:
Member %s not found for type %s.
Attempting to cast something to a type that doesn't apply:
Expression of type '%s' cannot be cast as a value of type '%s'.
Attempting to use a library as an expression:
Identifier %s is a library and cannot be used as an expression.
Attempting to use an expression in a context where it doesn't make sense:
Expected an expression of type '%s', but found an expression of type '%s'.
Using singleton from
on an expression that isn't a list:
List type expected.
Using point from
, starts
or ends
on an expression that isn't an interval:
Interval type expected.
Using convert
to convert between types that cannot be converted (for example a number to a datetime):
Could not resolve conversion from type %s to type %s.
Attempting to use an operator or function with arguments that don't apply:
Could not resolve call to operator %s with signature %s.
For example, attempting to add the number 5
and the string 'John'
:
5 + 'John'
Results in the error:
Could not resolve call to operator Add with signature (System.Integer,System.String)
This means that the Add
operator does not have a definition that supports the types Integer
and String
.
Attempting to use an operator or function that could be applied in multiple ways:
Call to operator %s is ambiguous among: %s, %s, …%s
For example, attempting to compare two laboratory test results in QDM:
define "Laboratory Tests": ["Laboratory Test, Performed": "XYZ"]
define "First Laboratory Test": First ( "Laboratory Tests" L sort by resultDatetime )
define "Last Laboratory Test": Last ( "Laboratory Tests" L sort by resultDatetime desc )
define "Compare Laboratory Tests":
"First Laboratory Test" F
with "Last Laboratory Test" L
such that F.result > L.result
This results in the error:
Call to operator Greater(choice<System.Integer,System.Decimal,System.Code,System.Quantity,QDM.Ratio>,choice<System.Integer,System.Decimal,System.Code,System.Quantity,QDM.Ratio>) is ambiguous with:
- Greater(System.Decimal,System.Decimal)
- Greater(System.Integer,System.Integer)
- Greater(System.Quantity,System.Quantity)
This happens because in QDM, the result
element for a Laboratory Test, Performed
supports communicating results as integers, decimals, codes, quantities, and ratios. Since the Greater
(>
) operator is defined for integers, decimals, and quantities, the invocation is ambiguous between the three. To correct this, indicate which type to use by treating (or casting) the element as a particular type using the as
operator:
define "Compare Laboratory Tests":
"First Laboratory Test" F
with "Last Laboratory Test" L
such that (F.result as Quantity) > (L.result as Quantity)
Attempting to sort the results of a singular query:
Sort clause cannot be used in a singular query.
Attempting to retrieve from an identifier that is not a type:
Could not resolve type name %s.
Attempting to retrieve from a type that does not support retrieval:
Specified data type %s does not support retrieval.
Retrieve has a terminology target but does not specify a code path and the type of the retrieve does not have a primary code path defined.
Could not resolve code path %s for the type of the retrieve %s.
Unexpected membership operator %s in retrieve
Could not resolve membership operator for terminology target of the retrieve.
Function %s has declared return type %s but the function body returns incompatible type %s.
Function %s is marked external but does not declare a return type.
Authoring Patterns - QICore v4.1.1
Authoring Patterns - QICore v5.0.0
Authoring Patterns - QICore v6.0.0
Cooking with CQL Q&A All Categories
Additional Q&A Examples
Developers Introduction to CQL
Specifying Population Criteria