Skip to content

Commit 54a0d3a

Browse files
authored
Merge pull request #2208 from aehrc/issue/2149
Correcting the count, exits and empty for empty collections.
2 parents 1efed63 + a2e678f commit 54a0d3a

File tree

17 files changed

+104
-133
lines changed

17 files changed

+104
-133
lines changed

fhirpath/src/main/java/au/csiro/pathling/fhirpath/collection/EmptyCollection.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import au.csiro.pathling.fhirpath.FhirPathType;
44
import au.csiro.pathling.fhirpath.column.ColumnRepresentation;
5-
import au.csiro.pathling.fhirpath.column.EmptyRepresentation;
5+
import au.csiro.pathling.fhirpath.column.DefaultRepresentation;
66
import au.csiro.pathling.fhirpath.definition.NodeDefinition;
77
import au.csiro.pathling.fhirpath.operator.Comparable;
88
import jakarta.annotation.Nonnull;
@@ -16,7 +16,7 @@
1616
public class EmptyCollection extends Collection {
1717

1818
private static final EmptyCollection INSTANCE = new EmptyCollection(
19-
EmptyRepresentation.getInstance(), Optional.empty(), Optional.empty(), Optional.empty(),
19+
DefaultRepresentation.empty(), Optional.empty(), Optional.empty(), Optional.empty(),
2020
Optional.empty());
2121

2222
protected EmptyCollection(@Nonnull final ColumnRepresentation column,

fhirpath/src/main/java/au/csiro/pathling/fhirpath/collection/mixed/MixedCollection.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package au.csiro.pathling.fhirpath.collection.mixed;
22

33
import au.csiro.pathling.fhirpath.collection.Collection;
4-
import au.csiro.pathling.fhirpath.column.EmptyRepresentation;
4+
import au.csiro.pathling.fhirpath.column.DefaultRepresentation;
55
import au.csiro.pathling.fhirpath.definition.ChoiceDefinition;
66
import jakarta.annotation.Nonnull;
77
import java.util.Optional;
@@ -16,7 +16,7 @@
1616
public abstract class MixedCollection extends Collection {
1717

1818
protected MixedCollection() {
19-
super(EmptyRepresentation.getInstance(), Optional.empty(), Optional.empty(), Optional.empty(),
19+
super(DefaultRepresentation.empty(), Optional.empty(), Optional.empty(), Optional.empty(),
2020
Optional.empty());
2121
}
2222

fhirpath/src/main/java/au/csiro/pathling/fhirpath/column/ColumnRepresentation.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
* @author John Grimes
5555
*/
5656
public abstract class ColumnRepresentation {
57-
57+
5858
/**
5959
* Create a new {@link ColumnRepresentation} from the result of a function that takes two
6060
* {@link Column} operands and returns a single {@link Column} result.
@@ -414,7 +414,7 @@ public ColumnRepresentation countDistinct() {
414414
* @return A new {@link ColumnRepresentation} that is the result of the check
415415
*/
416416
@Nonnull
417-
public ColumnRepresentation empty() {
417+
public ColumnRepresentation isEmpty() {
418418
return vectorize(
419419
c -> when(c.isNotNull(), size(c).equalTo(0)).otherwise(true),
420420
Column::isNull);

fhirpath/src/main/java/au/csiro/pathling/fhirpath/column/DefaultRepresentation.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import lombok.Getter;
3131
import lombok.ToString;
3232
import org.apache.spark.sql.Column;
33+
import org.apache.spark.sql.functions;
3334
import org.hl7.fhir.r4.model.Enumerations.FHIRDefinedType;
3435

3536
/**
@@ -44,7 +45,23 @@
4445
@AllArgsConstructor
4546
public class DefaultRepresentation extends ColumnRepresentation {
4647

47-
Column value;
48+
private static final DefaultRepresentation EMPTY_REPRESENTATION = new DefaultRepresentation(
49+
functions.lit(null));
50+
51+
/**
52+
* Gets the empty representation.
53+
*
54+
* @return A singleton instance of an empty representation
55+
*/
56+
@Nonnull
57+
public static ColumnRepresentation empty() {
58+
return EMPTY_REPRESENTATION;
59+
}
60+
61+
/**
62+
* The column value represented by this object.
63+
*/
64+
private Column value;
4865

4966
/**
5067
* Create a new {@link ColumnRepresentation} from a literal value.
@@ -53,7 +70,7 @@ public class DefaultRepresentation extends ColumnRepresentation {
5370
* @return A new {@link ColumnRepresentation} representing the value
5471
*/
5572
@Nonnull
56-
public static ColumnRepresentation literal(@Nonnull final Object value) {
73+
public static DefaultRepresentation literal(@Nonnull final Object value) {
5774
if (value instanceof BigDecimal) {
5875
// If the literal is a BigDecimal, represent it as a DecimalRepresentation.
5976
return new DecimalRepresentation(lit(value));
@@ -120,5 +137,5 @@ protected Column traverseColumn(@Nonnull final String fieldName) {
120137
public ColumnRepresentation getField(@Nonnull final String fieldName) {
121138
return copyOf(value.getField(fieldName));
122139
}
123-
140+
124141
}

fhirpath/src/main/java/au/csiro/pathling/fhirpath/column/EmptyRepresentation.java

Lines changed: 0 additions & 72 deletions
This file was deleted.

fhirpath/src/main/java/au/csiro/pathling/fhirpath/execution/NullEvaluator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package au.csiro.pathling.fhirpath.execution;
22

33
import au.csiro.pathling.fhirpath.collection.ResourceCollection;
4-
import au.csiro.pathling.fhirpath.column.EmptyRepresentation;
4+
import au.csiro.pathling.fhirpath.column.DefaultRepresentation;
55
import au.csiro.pathling.fhirpath.function.registry.StaticFunctionRegistry;
66
import ca.uhn.fhir.context.FhirContext;
77
import jakarta.annotation.Nonnull;
@@ -26,7 +26,7 @@ static class NullResourceResolver extends BaseResourceResolver {
2626
@Nonnull
2727
protected ResourceCollection createResource(@Nonnull final ResourceType resourceType) {
2828
return ResourceCollection.build(
29-
new EmptyRepresentation(),
29+
DefaultRepresentation.empty(),
3030
getFhirContext(), resourceType);
3131
}
3232
}

fhirpath/src/main/java/au/csiro/pathling/fhirpath/function/provider/ExistenceFunctions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public static BooleanCollection exists(@Nonnull final Collection input,
6060
@FhirPathFunction
6161
@Nonnull
6262
public static BooleanCollection empty(@Nonnull final Collection input) {
63-
return BooleanCollection.build(input.getColumn().empty());
63+
return BooleanCollection.build(input.getColumn().isEmpty());
6464
}
6565

6666
/**

fhirpath/src/main/java/au/csiro/pathling/fhirpath/function/provider/TerminologyFunctions.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import au.csiro.pathling.fhirpath.collection.StringCollection;
2929
import au.csiro.pathling.fhirpath.column.ColumnRepresentation;
3030
import au.csiro.pathling.fhirpath.column.DefaultRepresentation;
31-
import au.csiro.pathling.fhirpath.column.EmptyRepresentation;
3231
import au.csiro.pathling.fhirpath.definition.ElementDefinition;
3332
import au.csiro.pathling.fhirpath.function.FhirPathFunction;
3433
import au.csiro.pathling.sql.udf.PropertyUdf;
@@ -71,7 +70,7 @@ public static StringCollection display(@Nonnull final CodingCollection input,
7170
.transformWithUdf("display", Optional.ofNullable(language)
7271
.map(StringCollection::getColumn)
7372
.map(ColumnRepresentation::singular)
74-
.orElse(EmptyRepresentation.getInstance()))
73+
.orElse(DefaultRepresentation.empty()))
7574
.removeNulls()
7675
);
7776
}
@@ -122,7 +121,7 @@ public static Collection property(@Nonnull final CodingCollection input,
122121
Optional.ofNullable(language)
123122
.map(StringCollection::getColumn)
124123
.map(ColumnRepresentation::singular)
125-
.orElse(EmptyRepresentation.getInstance())
124+
.orElse(DefaultRepresentation.empty())
126125
).flatten().removeNulls();
127126

128127
return Collection.build(resultCtx, propertyType,
@@ -160,11 +159,11 @@ public static StringCollection designation(@Nonnull final CodingCollection input
160159
Optional.ofNullable(use)
161160
.map(CodingCollection::getColumn)
162161
.map(ColumnRepresentation::singular)
163-
.orElse(EmptyRepresentation.getInstance()),
162+
.orElse(DefaultRepresentation.empty()),
164163
Optional.ofNullable(language)
165164
.map(StringCollection::getColumn)
166165
.map(ColumnRepresentation::singular)
167-
.orElse(EmptyRepresentation.getInstance())
166+
.orElse(DefaultRepresentation.empty())
168167
)
169168
.flatten().removeNulls()
170169
);
@@ -279,7 +278,7 @@ public static CodingCollection translate(@Nonnull final Concepts input,
279278
.transform(c -> functions.split(c, ",")),
280279
Optional.ofNullable(target).map(StringCollection::getColumn)
281280
.map(ColumnRepresentation::singular)
282-
.orElse(EmptyRepresentation.getInstance())
281+
.orElse(DefaultRepresentation.empty())
283282
));
284283
}
285284

fhirpath/src/main/java/au/csiro/pathling/view/UnnestingSelection.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import au.csiro.pathling.fhirpath.FhirPath;
2626
import au.csiro.pathling.fhirpath.collection.Collection;
2727
import au.csiro.pathling.fhirpath.column.DefaultRepresentation;
28-
import au.csiro.pathling.fhirpath.column.EmptyRepresentation;
2928
import jakarta.annotation.Nonnull;
3029
import java.util.List;
3130
import java.util.stream.Collectors;
@@ -71,7 +70,7 @@ public ProjectionResult evaluate(@Nonnull final ProjectionContext context) {
7170

7271
// This is a way to evaluate the expression for the purpose of getting the types of the result.
7372
final ProjectionContext stubContext = context.withInputContext(
74-
unnestingCollection.map(__ -> EmptyRepresentation.getInstance()));
73+
unnestingCollection.map(__ -> DefaultRepresentation.empty()));
7574
final List<ProjectionResult> stubResults = components.stream()
7675
.map(s -> s.evaluate(stubContext))
7776
.toList();

fhirpath/src/test/java/au/csiro/pathling/fhirpath/column/DefaultRepresentationTest.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,11 @@ void testNot() {
176176
@Test
177177
void testEmpty() {
178178
new ColumnAsserts()
179-
.assertEquals(true, nullValue().empty())
180-
.assertEquals(false, valueOf(17).empty())
181-
.assertEquals(true, nullArray().empty())
182-
.assertEquals(true, emptyArray().empty())
183-
.assertEquals(false, arrayOf(1, 2, 3).empty())
179+
.assertEquals(true, nullValue().isEmpty())
180+
.assertEquals(false, valueOf(17).isEmpty())
181+
.assertEquals(true, nullArray().isEmpty())
182+
.assertEquals(true, emptyArray().isEmpty())
183+
.assertEquals(false, arrayOf(1, 2, 3).isEmpty())
184184
.check();
185185
}
186186

fhirpath/src/test/java/au/csiro/pathling/fhirpath/yaml/YamlFhirpathTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package au.csiro.pathling.fhirpath.yaml;
22

3+
import au.csiro.pathling.test.yaml.YamlConfig;
34
import au.csiro.pathling.test.yaml.YamlSpec;
45
import au.csiro.pathling.test.yaml.YamlSpecTestBase;
56
import jakarta.annotation.Nonnull;
@@ -9,6 +10,9 @@
910

1011
@Slf4j
1112
@Tag("UnitTest")
13+
@YamlConfig(
14+
resourceBase = "fhirpath-ptl/resources"
15+
)
1216
public class YamlFhirpathTest extends YamlSpecTestBase {
1317

1418
@YamlSpec("fhirpath-ptl/cases/literals.yaml")

fhirpath/src/test/java/au/csiro/pathling/fhirpath/yaml/YamlReferenceImplTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515

1616
@Slf4j
1717
@Tag("YamlTest")
18-
@YamlConfig("fhirpath-js/config.yaml")
18+
@YamlConfig(
19+
config = "fhirpath-js/config.yaml",
20+
resourceBase = "fhirpath-js/resources"
21+
)
1922
public class YamlReferenceImplTest extends YamlSpecCachedTestBase {
2023

2124

fhirpath/src/test/java/au/csiro/pathling/test/yaml/YamlConfig.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,7 @@
66
@Retention(RetentionPolicy.RUNTIME)
77
public @interface YamlConfig {
88

9-
String value();
9+
String config() default "";
10+
11+
String resourceBase() default "";
1012
}

fhirpath/src/test/java/au/csiro/pathling/test/yaml/YamlSpecTestBase.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import ca.uhn.fhir.parser.IParser;
2828
import jakarta.annotation.Nonnull;
2929
import jakarta.annotation.Nullable;
30+
import java.io.File;
3031
import java.math.BigDecimal;
3132
import java.math.RoundingMode;
3233
import java.util.List;
@@ -342,8 +343,17 @@ public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
342343

343344
final Optional<String> testConfigPath = context.getTestClass()
344345
.flatMap(c -> Optional.ofNullable(c.getAnnotation(YamlConfig.class)))
345-
.map(YamlConfig::value);
346+
.map(YamlConfig::config)
347+
.filter(s -> !s.isBlank());
348+
349+
final Optional<String> resourceBase = context.getTestClass()
350+
.flatMap(c -> Optional.ofNullable(c.getAnnotation(YamlConfig.class)))
351+
.map(YamlConfig::resourceBase)
352+
.filter(s -> !s.isBlank());
353+
346354
testConfigPath.ifPresent(s -> log.info("Loading test config from: {}", s));
355+
resourceBase.ifPresent(s -> log.info("Resource base : {}", s));
356+
347357
final TestConfig testConfig = testConfigPath
348358
.map(TestResources::getResourceAsString)
349359
.map(TestConfig::fromYaml)
@@ -376,7 +386,7 @@ public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
376386
.map(ts -> StdRuntimeCase.of(ts,
377387
Optional.ofNullable(ts.getInputFile())
378388
.map(f -> (Function<RuntimeContext, ResourceResolver>) FhirResolverFactory.of(
379-
getResourceAsString("fhirpath-js/resources/" + f)))
389+
getResourceAsString(resourceBase.orElse("") + File.separator + f)))
380390
.orElse(defaultResolverFactory),
381391
excluder.apply(ts)
382392
))

0 commit comments

Comments
 (0)