Skip to content

Implement repeat directive for recursive traversal #2481

@johngrimes

Description

@johngrimes

Overview

This ticket is to implement the new repeat directive described in SQL on FHIR v2 PR #296.

Background

The repeat directive enables recursive traversal of nested structures in FHIR resources, automatically flattening hierarchical data to any depth. This is particularly useful for resources with recursive nesting patterns like QuestionnaireResponse items, where the depth of nesting is not known in advance.

Specification

Behaviour

The repeat directive takes an array of FHIRPath expressions that define paths to recursively traverse. The view runner will:

  1. Start at the current context node
  2. Evaluate each path expression
  3. For each result, recursively apply the same path patterns
  4. Continue until no more matches are found at any depth
  5. Union all results from all levels and all paths together

Example Usage

For a QuestionnaireResponse with nested groups and questions:

{
  "resource": "QuestionnaireResponse",
  "select": [
    {
      "repeat": [
        "item",
        "answer.item"
      ],
      "column": [
        {
          "path": "linkId",
          "name": "item_id"
        },
        {
          "path": "text",
          "name": "question_text"
        }
      ]
    }
  ]
}

This would produce a flat table with all items regardless of nesting depth.

Implementation Requirements

1. Schema Updates

  • Add repeat as a new field in ViewDefinition select structure
  • Type: Array of strings (FHIRPath expressions)
  • Cardinality: 0..*
  • Update the sql-expressions invariant to ensure only one of forEach, forEachOrNull, or repeat can be present

2. Core Algorithm

Implement the recursive traversal function as specified in the PR:

1. Initialize an empty list `result`
2. Define a recursive function `traverse(node, isRoot)`:
   - If not `isRoot`, add `node` to `result`
   - For each path `p` in `S.repeat`:
     - Evaluate `fhirpath(p, node)` to get child nodes
     - For each child node `c` in the result:
       - Recursively call `traverse(c, false)`
3. Call `traverse(N, true)` to start the traversal
4. Use `result` as the focus nodes for column evaluation

3. Integration Points

The repeat directive should:

  • Work alongside existing column selections
  • Be combinable with unionAll operations
  • Support nested select structures within repeat
  • Be compatible with forEach and forEachOrNull in nested selections (but not at the same level)

Acceptance Criteria

  • The repeat directive is available within the Pathling view runner
  • Recursive traversal works correctly for all SQL on FHIR test scenarios
  • Validation ensures mutual exclusivity with forEach/forEachOrNull at the same level
  • Documentation is updated to explain the feature
  • All existing tests continue to pass

References

Metadata

Metadata

Assignees

Labels

new featureNew feature or request

Type

No type

Projects

Status

In progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions