Skip to content

feat: Implement FHIRPath projection functions#2566

Open
piotrszul wants to merge 16 commits intomainfrom
issue/2388
Open

feat: Implement FHIRPath projection functions#2566
piotrszul wants to merge 16 commits intomainfrom
issue/2388

Conversation

@piotrszul
Copy link
Collaborator

Resolves #2388

piotrszul and others added 6 commits March 6, 2026 10:51
The benchmark POM was referencing an outdated parent version, causing
build failures. Added benchmark/pom.xml to the version update checklist
to prevent future version drift.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add the select(projection: expression) function to the FHIRPath engine,
which evaluates a projection expression for each item in the input
collection and flattens the results. This complements the existing
where() function by supporting element transformation rather than
filtering.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds the STU FHIRPath repeatAll() function which recursively evaluates a
projection expression on each item in the input collection, collecting
all results without deduplication. Uses Spark's Variant type as an
intermediate representation to handle schema divergence across nesting
levels in self-referential FHIR structures like Questionnaire.item.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract magic depth limit to named constant, make variantTransformTree()
delegate to variantUnwrap(), expose failOnError parameter in
UnresolvedVariantUnwrap, mark repeatAll with EXPERIMENTAL profile,
strengthen test assertions, and add clarifying comments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ResourceCollection.copyWith() was re-deriving the extension map from the
new column representation, which fails for non-resource structs (like
Extension) that lack the _extension field. This caused repeatAll(extension)
to only return top-level extensions, missing nested sub-extensions.

Added a private constructor that accepts an explicit extension map column,
and updated copyWith() to use it. Also consolidated RepeatAllFunctionDslTest
from 13 methods to 7 by chaining groups that share the same resource setup,
and refined the delta spec for same-type recursion depth scenarios.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
piotrszul and others added 10 commits March 6, 2026 12:27
…or repeatAll()

Replace hardcoded same-type recursion depth with configurable maxExtensionDepth
via FhirpathConfiguration. Non-Extension same-type depth exhaustion now raises
an error instead of silently returning bounded results, catching infinite
recursion in expressions like repeatAll($this) or repeatAll(first()).

Support EvaluationContext injection in FHIRPath function parameter resolution
so that functions can access configuration without changing the public API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…cally

Expressions like gender.repeatAll($this) are genuinely infinite but were
silently returning truncated results due to a primitive type shortcut that
bypassed recursion detection. Replaced the shortcut with a static type
analysis gate that applies the traversal expression twice (level_0 and
level_1) to classify behavior before any tree traversal. Non-recursive
traversals now return level_0 directly for all types, and self-referential
primitives raise an immediate error with a distinct message.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ication

Add repeat() as a wrapper around repeatAll() that deduplicates results
using the collection's equality comparator. Only Equatable types with a
FHIRPath type (primitives, Coding, Quantity) are deduplicated; complex
backbone elements are returned as-is.

Add allowPrimitiveSelfRef parameter to repeatAll() so repeat() can
handle self-referential primitive traversal where deduplication
guarantees termination.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…mprove error messages

The try-catch in mapChildren now only wraps the Catalyst resolution call,
preventing unrelated errors from being silently swallowed. Error messages
are made generic to work with both repeatAll() and repeat() functions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…repeat

Adds an explicit check for indeterminate FHIR types (empty getFhirType())
before the type consistency gate, preventing unresolved choice elements from
silently passing. Also treats resource types like primitives in the type
analysis gate, since they use boolean existence columns rather than structs.
Updates repeat() to suppress depth exhaustion errors via the allowSelfReference
flag, relying on deduplication for termination.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The config parameter controlled depth for all repeat()/repeatAll()
traversals, not just Extensions. Renamed to align with the existing
QueryConfiguration.maxUnboundTraversalDepth naming. Also simplified
redundant instanceof Equatable check in Collection.repeat().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tion

Wire QueryConfiguration.maxUnboundTraversalDepth through to FHIRPath
evaluation so repeat()/repeatAll() respect user-configured depth limits.
Align @min constraint to 1 on both config classes. Make ViewDefinition
repeat clause error on non-Extension depth exhaustion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cover unresolved state, withNewChildrenInternal, mapChildren resolution
with ArrayType and non-ArrayType schemas, and failOnError propagation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cover Variant-based tree traversal with schema divergence, depth
limiting, error-on-exhaustion, and direct Variant round-trip unwrapping.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract duplicated "unknown" literal into constant, replace lambdas
with method references, fix variable naming conventions, and remove
unnecessary public modifier on test class.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sonarqubecloud
Copy link

@piotrszul piotrszul self-assigned this Mar 10, 2026
@github-project-automation github-project-automation bot moved this to Backlog in Pathling Mar 10, 2026
@piotrszul piotrszul added the fhirpath Related to fhirpath reference implementation label Mar 10, 2026
@piotrszul piotrszul moved this from Backlog to In progress in Pathling Mar 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fhirpath Related to fhirpath reference implementation

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

Support all filtering and projection functions

1 participant