You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a FHIRPath collection contains Quantity values with different structural shapes (for example, an indefinite calendar duration alongside a UCUM quantity, or UCUM quantities with different canonical units that normalise differently), applying repeat($this) over that collection fails. The failure originates in Pathling's Quantity canonicalisation: structurally-different Quantity literals produce structs whose subfields differ in nullability, and repeat() subsequently casts those struct elements to VARIANT for deduplication, which rejects the heterogeneous shape.
This bug is independent of combine() — combine() is simply the cleanest way to build a collection that exposes it, because it concatenates without deduplicating away the mismatched structs. The same underlying canonicalisation shape mismatch is also what produces the wontfix "Indefinite calendar duration union deduplication" exclusion ((1 year | 12 months)) in fhirpath/src/test/resources/fhirpath-js/config.yaml.
Reproduction
Both expressions fail in Pathling and are currently excluded from the fhirpath-js reference test suite (config.yaml:179-192):
The first case mixes an indefinite calendar duration (year) with a definite one (month); the second mixes two UCUM units that canonicalise to different base representations.
Root cause (suspected)
Pathling's Quantity encoding uses a struct with fields for the original value/unit/system/code plus canonicalised value/unit fields used for equality and comparison. Indefinite calendar durations (year, month) leave the canonical subfields null, whereas UCUM quantities populate them. When two literals of these different classes end up in the same array, the resulting Spark array contains structs whose subfield nullabilities are inconsistent.
repeat()'s deduplication path casts the element struct to VARIANT, and Spark's VARIANT casting is strict about schema homogeneity within an array, so the cast fails.
Expected behaviour
repeat(\$this) over a heterogeneous Quantity collection should return the collection (each element is its own fixed point under \$this). It should not raise a canonicalisation/cast error.
Suggested fix directions
Normalise Quantity struct shape at encoding time — emit a consistent schema where every subfield is always present (possibly with null values) regardless of whether the literal is a calendar duration or a UCUM quantity.
Avoid VARIANT casting in repeat() for struct-typed collections — use a deduplication strategy that honours the collection's comparator instead, mirroring the approach already used by UnionOperator / CombiningLogic.dedupeArray for types with custom equality.
Option 1 would also unblock the related wontfix exclusion on indefinite calendar duration union deduplication.
Impact
Currently blocks repeat() / deduplication-based operations over any collection that mixes structurally-different Quantity literals.
Surfaces via combine() (new in Support combining functions #2384) but is a latent issue in the Quantity encoder, not in the combining functions.
Summary
When a FHIRPath collection contains Quantity values with different structural shapes (for example, an indefinite calendar duration alongside a UCUM quantity, or UCUM quantities with different canonical units that normalise differently), applying
repeat($this)over that collection fails. The failure originates in Pathling's Quantity canonicalisation: structurally-different Quantity literals produce structs whose subfields differ in nullability, andrepeat()subsequently casts those struct elements toVARIANTfor deduplication, which rejects the heterogeneous shape.This bug is independent of
combine()—combine()is simply the cleanest way to build a collection that exposes it, because it concatenates without deduplicating away the mismatched structs. The same underlying canonicalisation shape mismatch is also what produces thewontfix"Indefinite calendar duration union deduplication" exclusion ((1 year | 12 months)) infhirpath/src/test/resources/fhirpath-js/config.yaml.Reproduction
Both expressions fail in Pathling and are currently excluded from the
fhirpath-jsreference test suite (config.yaml:179-192):The first case mixes an indefinite calendar duration (year) with a definite one (month); the second mixes two UCUM units that canonicalise to different base representations.
Root cause (suspected)
Pathling's Quantity encoding uses a struct with fields for the original value/unit/system/code plus canonicalised value/unit fields used for equality and comparison. Indefinite calendar durations (year, month) leave the canonical subfields null, whereas UCUM quantities populate them. When two literals of these different classes end up in the same array, the resulting Spark array contains structs whose subfield nullabilities are inconsistent.
repeat()'s deduplication path casts the element struct toVARIANT, and Spark'sVARIANTcasting is strict about schema homogeneity within an array, so the cast fails.Expected behaviour
repeat(\$this)over a heterogeneous Quantity collection should return the collection (each element is its own fixed point under\$this). It should not raise a canonicalisation/cast error.Suggested fix directions
VARIANTcasting inrepeat()for struct-typed collections — use a deduplication strategy that honours the collection's comparator instead, mirroring the approach already used byUnionOperator/CombiningLogic.dedupeArrayfor types with custom equality.Option 1 would also unblock the related
wontfixexclusion on indefinite calendar duration union deduplication.Impact
repeat()/ deduplication-based operations over any collection that mixes structurally-different Quantity literals.combine()(new in Support combining functions #2384) but is a latent issue in the Quantity encoder, not in the combining functions.References
union()/combine()functions), PR feat: Support FHIRPath union() and combine() combining functions #2587.fhirpath/src/test/resources/fhirpath-js/config.yaml:179-192.wontfixexclusion: "Indefinite calendar duration union deduplication" in the same file.