Skip to content

Commit

Permalink
Ensure unions have aligned column names
Browse files Browse the repository at this point in the history
  • Loading branch information
jmandel committed Oct 24, 2023
1 parent c5053c7 commit 5581758
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 12 deletions.
29 changes: 27 additions & 2 deletions tests/content/union.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,17 @@
"union": [
{
"forEach": "name",
"column": [{ "path": "family", "name": "a" }]
"column": [
{ "path": "family", "name": "a" },
{ "path": "{}", "name": "b" }
]
},
{
"forEach": "contact.name",
"column": [{ "path": "family", "name": "b" }]
"column": [
{ "path": "family", "name": "b" },
{ "path": "{}", "name": "a" }
]
}
]
}
Expand All @@ -67,6 +73,25 @@
{ "a": null, "b": "f3" }
]
},
{
"title": "Union with mismatching branches",
"view": {
"resource": "Patient",
"select": [
{
"union": [
{
"column": [{ "path": "'a'", "name": "a" }]
},
{
"column": [{ "path": "'b'", "name": "b" }]
}
]
}
]
},
"expectError": true
},
{
"title": "Union with forEachOrNull",
"view": {
Expand Down
13 changes: 10 additions & 3 deletions tests/generate.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { runTests } from './reference-implementation/index.js'
import { runTests, getColumns } from './reference-implementation/index.js'
import fhirpath from 'fhirpath'
import Ajv from 'ajv'
import fs from 'fs'
Expand All @@ -18,6 +18,7 @@ function validatePathToSubset(path) {
'Identifier',
'LiteralTerm',
'BooleanLiteral',
'NullLiteral',
'StringLiteral',
'NumberLiteral',
'MemberInvocation',
Expand Down Expand Up @@ -71,18 +72,24 @@ function validatePathToSubset(path) {
}
}
const ast = fhirpath.parse(path)
return validateChildren(ast)
const problems = validateChildren(ast)
if (problems) {
throw problems
}
}

function buildFhirpathFormat(allowExtendedFhirpath) {
return {
type: 'string',
validate: (v) => {
try {
if (!allowExtendedFhirpath && validatePathToSubset(v)) return false
if (!allowExtendedFhirpath) {
validatePathToSubset(v)
}
fhirpath.compile(v)
return true
} catch (err) {
console.log('Invalid fhirpath', v, err)
return false
}
},
Expand Down
20 changes: 13 additions & 7 deletions tests/reference-implementation/extractor.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,18 @@ function compileViewDefinition(viewDefinition) {
for (let field of subViews(viewDefinition)) {
compileViewDefinition(field)
}

const cols = (viewDefinition.union ?? [])
.map((u) =>
getColumns({ select: [u] })
.reduce((acc, c) => acc.concat(c.name), [])
.sort(),
)
.map((u) => JSON.stringify(u))

if (cols.some((c) => c !== cols[0])) {
throw `Unions use different columns: ${cols}`
}
}

function cartesianProduct([first, ...rest]) {
Expand Down Expand Up @@ -122,15 +134,9 @@ function extractFields(obj, viewDefinition, context = {}) {
}

const unionBindings = []
const unionColumns = getColumns({ union })
.reduce((acc, c) => {
acc[c.name] = null
return acc
}, {})

for (const u of union ?? []) {
for (const r of extract(nestedObject, { select: [u] }, context)) {
unionBindings.push({ ...unionColumns, ...r })
unionBindings.push(r)
}
}

Expand Down

0 comments on commit 5581758

Please sign in to comment.