-
Notifications
You must be signed in to change notification settings - Fork 21
Open
Description
Summary
The SDK fails to parse/resolve namespace-qualified library names in CQL library and include declarations. This prevents consumers from organizing libraries by namespace (e.g., MyOrg.FHIR.Measurement) and breaks interop with tooling/spec-compliant CQL that uses namespace-scoped names.
Impact
- CQL with qualified library identifiers cannot be compiled/resolved.
- Breaks modularization and reuse across teams/orgs.
- Blocks adoption in environments where standards or internal guidelines require namespaces.
- Causes runtime and/or compile-time errors in evaluation pipelines.
Examples
Problematic CQL (namespace-qualified library name):
CQL
library "MyOrg.FHIR.Measurement" version '1.2.3'
using FHIR version '4.0.1'
include "MyOrg.FHIR.Common" version '1.0.0' called Common
include "FHIRHelpers" version '4.0.1' called FHIRHelpers
context Patient
define "Adult":
AgeInYears() >= 18Observed behavior:
- Parser rejects the
libraryidentifier due to.in the name or - Library resolver treats the fully-qualified name as invalid/unknown and fails to locate the resource (e.g., expects simple identifiers only).
Expected behavior:
- Parser accepts namespace-qualified library identifiers (e.g.,
MyOrg.FHIR.Measurement). - Resolver locates libraries by fully-qualified name + version (and supports mapping to physical package/file names).
includeworks with namespace-qualified libraries and aliases.
Steps to Reproduce
-
Create a CQL file with a namespace-qualified library name and an
includereferencing another qualified library:CQL
library "Acme.Quality.HEDIS" version '0.9.0' using FHIR version '4.0.1' include "Acme.Common" version '1.0.0' called Common // ... rest of library
-
Compile/parse the CQL via the SDK:
C#
// Pseudocode var result = CqlCompiler.Compile("Acme.Quality.HEDIS.cql", options);
-
Observe failure (parse error or unresolved include).
Actual Result
- Parser error such as:
Invalid library identifier token '.' at position ...
or - Resolution error such as:
Library 'Acme.Quality.HEDIS' (0.9.0) not found.
Expected Result
- Compilation succeeds; AST preserves fully-qualified identifiers.
- Library resolution resolves
Acme.Quality.HEDISandAcme.Commonby namespace + version. - Generated ELM includes the correct library identifiers.
Logs / Error Messages (sample)
[Parser] Unexpected token '.' after Identifier at line 1, column 15.
[Resolver] Could not resolve library 'MyOrg.FHIR.Common' version '1.0.0'.
Technical Notes / Hypothesis
- Lexer/Parser likely restricts
identifierto[A-Za-z_][A-Za-z0-9_]*and rejects dotted qualifiers. - Symbol Table / Resolver assumes a flat library namespace (simple names only) and does not support namespacing in keys.
- File/URI mapping may need configuration to translate qualified library names to paths (e.g.,
MyOrg/FHIR/Measurement.cqlorMyOrg.FHIR.Measurement.cql). - Version strategy should remain unchanged; only identifier parsing/matching expands.
- Backwards compatibility: Simple identifiers must remain valid.
Proposed Fix (Outline)
-
Grammar: Extend
LibraryIdentifierto accept dot-separated segments, e.g.:LibraryIdentifier := Identifier ('.' Identifier)* -
Resolver:
- Use fully-qualified name as the primary key in the library registry.
- Support a pluggable name-to-resource mapping (e.g., provider callback) for custom path conventions.
-
ELM:
- Ensure emitted ELM preserves
library.identifier.id = "MyOrg.FHIR.Measurement".
- Ensure emitted ELM preserves
-
Includes:
- Normalize includes to fully-qualified form for matching; enforce version semantics unchanged.
-
Diagnostics:
- Improve error messages to distinguish parse vs resolution failures.
-
Tests:
- Unit tests for parsing qualified names (
a.b,a.b.c), mixed includes, and aliasing. - Resolver tests for mapping rules and versioned lookup.
- Round-trip tests: CQL → ELM → execution with qualified libraries.
- Unit tests for parsing qualified names (
Acceptance Criteria
- ✅ CQL with namespace-qualified library identifiers parses successfully.
- ✅
includestatements with qualified names resolve when available via configured providers. - ✅ ELM output preserves qualified identifiers.
- ✅ Existing CQL with simple names remains unaffected.
- ✅ Comprehensive tests added and passing (parser, resolver, integration).
- ✅ Documentation updated: how to configure library resolution for namespaces (file layout, package naming, nuget/zip rules, etc.).
Workarounds (Current)
- Rename libraries to simple identifiers (undesirable, breaks namespacing).
- Add a preprocessing step to rewrite qualified names → simple names (lossy and fragile).
- Maintain a manual mapping in the resolver for specific libraries (not scalable).
Related / References
- Internal: link to SDK parser grammar file, resolver component, and library provider interface.
- Spec alignment: CQL identifier and library naming conventions (ensure we align with how tools expect qualified identifiers; note that some tools use simple names only, but organizations commonly need namespace scoping).
Attachments
- Minimal failing CQL files (2--3 small examples).
- Parser logs and call stack.
- Current grammar snippet and proposed diff.
- Unit tests demonstrating failure (before) and success (after).
Additional context**
Reactions are currently unavailable