Skip to content

Commit 414ddff

Browse files
committed
HSEARCH-5471 Account for null aggregated values
1 parent fb35fb3 commit 414ddff

File tree

14 files changed

+228
-48
lines changed

14 files changed

+228
-48
lines changed

backend/lucene/src/main/java/org/hibernate/search/backend/lucene/types/aggregation/impl/AbstractLuceneMetricCompensatedSumAggregation.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ private static class DoubleExtractedValueConverter<E extends Number> extends Ext
124124

125125
@Override
126126
Double convert(E extracted, FromDocumentValueConvertContext context) {
127-
return extracted.doubleValue();
127+
return extracted == null ? null : extracted.doubleValue();
128128
}
129129
}
130130

@@ -137,7 +137,7 @@ private RawExtractedValueConverter(ProjectionConverter<E, T> projectionConverter
137137

138138
@Override
139139
T convert(E extracted, FromDocumentValueConvertContext context) {
140-
return projectionConverter.fromDocumentValue( extracted, context );
140+
return extracted == null ? null : projectionConverter.fromDocumentValue( extracted, context );
141141
}
142142
}
143143

@@ -153,7 +153,7 @@ private DecodingExtractedValueConverter(ProjectionConverter<F, T> projectionConv
153153

154154
@Override
155155
T convert(E extracted, FromDocumentValueConvertContext context) {
156-
return projectionConverter.fromDocumentValue( codec.decode( extracted ), context );
156+
return extracted == null ? null : projectionConverter.fromDocumentValue( codec.decode( extracted ), context );
157157
}
158158
}
159159

backend/lucene/src/main/java/org/hibernate/search/backend/lucene/types/aggregation/impl/AbstractLuceneMetricNumericFieldAggregation.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,13 @@ private LuceneNumericMetricFieldAggregationExtraction(CollectorKey<?, Long> coll
7171

7272
@Override
7373
public K extract(AggregationExtractContext context) {
74-
Long collector = context.getCollectorResults( collectorKey );
75-
76-
E e = codec.getDomain().sortedDocValueToTerm( collector );
77-
F decode = codec.decode( e );
78-
return fromFieldValueConverter.fromDocumentValue( decode, context.fromDocumentValueConvertContext() );
74+
Long aggregatedValue = context.getCollectorResults( collectorKey );
75+
if ( aggregatedValue == null ) {
76+
return null;
77+
}
78+
E e = codec.getDomain().sortedDocValueToTerm( aggregatedValue );
79+
F decoded = codec.decode( e );
80+
return fromFieldValueConverter.fromDocumentValue( decoded, context.fromDocumentValueConvertContext() );
7981
}
8082

8183
private static class Builder<F, E extends Number, K> extends AbstractExtractorBuilder<F, E, K> {
@@ -110,9 +112,12 @@ private LuceneNumericMetricFieldAggregationDoubleExtractor(CollectorKey<?, Long>
110112

111113
@Override
112114
public Double extract(AggregationExtractContext context) {
113-
Long collector = context.getCollectorResults( collectorKey );
115+
Long aggregatedValue = context.getCollectorResults( collectorKey );
116+
if ( aggregatedValue == null ) {
117+
return null;
118+
}
114119

115-
return codec.sortedDocValueToDouble( collector );
120+
return codec.sortedDocValueToDouble( aggregatedValue );
116121
}
117122

118123
private static class Builder<F, E extends Number> extends AbstractExtractorBuilder<F, E, Double> {
@@ -142,8 +147,11 @@ private LuceneNumericMetricFieldAggregationRawExtraction(CollectorKey<?, Long> c
142147
@SuppressWarnings("unchecked")
143148
@Override
144149
public K extract(AggregationExtractContext context) {
145-
Long collector = context.getCollectorResults( collectorKey );
146-
return (K) numericDomain.sortedDocValueToTerm( collector );
150+
Long aggregatedValue = context.getCollectorResults( collectorKey );
151+
if ( aggregatedValue == null ) {
152+
return null;
153+
}
154+
return (K) numericDomain.sortedDocValueToTerm( aggregatedValue );
147155
}
148156

149157
private static class Builder<F, E extends Number, K> extends AbstractExtractorBuilder<F, E, K> {

backend/lucene/src/main/java/org/hibernate/search/backend/lucene/types/aggregation/impl/LuceneAvgCompensatedSumAggregation.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ void fillCollectors(JoiningLongMultiValuesSource source, AggregationRequestConte
4242
@Override
4343
E extractEncoded(AggregationExtractContext context, LuceneNumericDomain<E> numericDomain) {
4444
Double sum = context.getCollectorResults( compensatedSumCollectorKey );
45+
if ( sum == null ) {
46+
return null;
47+
}
4548
Long counts = context.getCollectorResults( collectorKey );
4649
double avg = ( sum / counts );
4750
return numericDomain.doubleToTerm( avg );

backend/lucene/src/main/java/org/hibernate/search/backend/lucene/types/aggregation/impl/LuceneAvgNumericFieldAggregation.java

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,15 @@ private LuceneNumericMetricFieldAggregationExtraction(CollectorKey<?, Long> coll
5757

5858
@Override
5959
public K extract(AggregationExtractContext context) {
60-
Long collector = context.getCollectorResults( collectorKey );
60+
Long aggregatedSum = context.getCollectorResults( collectorKey );
61+
if ( aggregatedSum == null ) {
62+
return null;
63+
}
6164
Long counts = context.getCollectorResults( countCollectorKey );
62-
Double avg = ( (double) collector / counts );
63-
collector = NumberUtils.toLong( avg );
65+
Double avg = ( (double) aggregatedSum / counts );
66+
aggregatedSum = NumberUtils.toLong( avg );
6467

65-
E e = codec.getDomain().sortedDocValueToTerm( collector );
68+
E e = codec.getDomain().sortedDocValueToTerm( aggregatedSum );
6669
F decode = codec.decode( e );
6770
return fromFieldValueConverter.fromDocumentValue( decode, context.fromDocumentValueConvertContext() );
6871
}
@@ -103,9 +106,13 @@ private LuceneNumericMetricFieldAggregationDoubleExtraction(CollectorKey<?, Long
103106

104107
@Override
105108
public Double extract(AggregationExtractContext context) {
106-
double collector = codec.sortedDocValueToDouble( context.getCollectorResults( collectorKey ) );
109+
Long aggregatedSum = context.getCollectorResults( collectorKey );
110+
if ( aggregatedSum == null ) {
111+
return null;
112+
}
113+
double docValueSum = codec.sortedDocValueToDouble( aggregatedSum );
107114
Long counts = context.getCollectorResults( countCollectorKey );
108-
return ( collector / counts );
115+
return ( docValueSum / counts );
109116
}
110117

111118
private static class Builder<F, E extends Number, K> extends AbstractExtractorBuilder<F, E, K> {
@@ -139,11 +146,14 @@ private LuceneNumericMetricFieldAggregationRawExtraction(CollectorKey<?, Long> c
139146

140147
@Override
141148
public E extract(AggregationExtractContext context) {
142-
Long collector = context.getCollectorResults( collectorKey );
149+
Long aggregatedSum = context.getCollectorResults( collectorKey );
150+
if ( aggregatedSum == null ) {
151+
return null;
152+
}
143153
Long counts = context.getCollectorResults( countCollectorKey );
144-
Double avg = ( (double) collector / counts );
145-
collector = NumberUtils.toLong( avg );
146-
return codec.getDomain().sortedDocValueToTerm( collector );
154+
Double avg = ( (double) aggregatedSum / counts );
155+
aggregatedSum = NumberUtils.toLong( avg );
156+
return codec.getDomain().sortedDocValueToTerm( aggregatedSum );
147157
}
148158

149159
private static class Builder<F, E extends Number, K> extends AbstractExtractorBuilder<F, E, K> {

backend/lucene/src/main/java/org/hibernate/search/backend/lucene/types/aggregation/impl/LuceneSumCompensatedSumAggregation.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ void fillCollectors(JoiningLongMultiValuesSource source, AggregationRequestConte
3737
@Override
3838
E extractEncoded(AggregationExtractContext context, LuceneNumericDomain<E> numericDomain) {
3939
Double sum = context.getCollectorResults( compensatedSumCollectorKey );
40+
if ( sum == null ) {
41+
return null;
42+
}
4043
return numericDomain.doubleToTerm( sum );
4144
}
4245

integrationtest/backend/elasticsearch/src/test/java/org/hibernate/search/integrationtest/backend/elasticsearch/testsupport/util/ElasticsearchTckBackendFeatures.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,4 +527,31 @@ private <U, R, A> R accumulatedNullValue(ProjectionCollector<Object, U, A, R> co
527527
values.add( null );
528528
return collector.finish( collector.accumulateAll( collector.createInitial(), values ) );
529529
}
530+
531+
@SuppressWarnings("unchecked") // because we ... did the equals check
532+
@Override
533+
public <T> T aggregatedSumNullValue(Class<T> clazz) {
534+
if ( String.class.equals( clazz ) ) {
535+
return (T) "0";
536+
}
537+
if ( Integer.class.equals( clazz ) ) {
538+
return (T) Integer.valueOf( 0 );
539+
}
540+
if ( Float.class.equals( clazz ) ) {
541+
return (T) Float.valueOf( 0.0f );
542+
}
543+
if ( Double.class.equals( clazz ) ) {
544+
return (T) Double.valueOf( 0.0 );
545+
}
546+
if ( BigInteger.class.equals( clazz ) ) {
547+
return (T) BigInteger.ZERO;
548+
}
549+
if ( BigDecimal.class.equals( clazz ) ) {
550+
return (T) BigDecimal.ZERO.setScale( 2 );
551+
}
552+
if ( LocalDate.class.equals( clazz ) ) {
553+
return (T) LocalDate.of( 1970, 1, 1 );
554+
}
555+
return super.aggregatedSumNullValue( clazz );
556+
}
530557
}

integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/aggregation/MetricNumericFieldsAggregationsIT.java

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.hibernate.search.engine.search.query.SearchQuery;
2727
import org.hibernate.search.engine.search.query.SearchResult;
2828
import org.hibernate.search.engine.search.query.dsl.SearchQueryOptionsStep;
29+
import org.hibernate.search.integrationtest.backend.tck.testsupport.util.TckConfiguration;
2930
import org.hibernate.search.integrationtest.backend.tck.testsupport.util.extension.SearchSetupHelper;
3031
import org.hibernate.search.util.common.data.Range;
3132
import org.hibernate.search.util.impl.integrationtest.mapper.stub.BulkIndexer;
@@ -148,6 +149,71 @@ void test_filteringResults() {
148149
);
149150
}
150151

152+
@Test
153+
void test_filteringNoResults() {
154+
StubMappingScope scope = mainIndex.createScope();
155+
SearchQueryOptionsStep<?, ?, DocumentReference, StubLoadingOptionsStep, ?, ?> options = scope.query()
156+
.where( f -> f.match().field( "style" ).matching( "foobar" ) );
157+
SearchQuery<DocumentReference> query = defineAggregations( options );
158+
159+
SearchResult<DocumentReference> result = query.fetch( 0 );
160+
assertThat( result.aggregation( sumIntegers ) )
161+
.isEqualTo( TckConfiguration.get().getBackendFeatures().aggregatedSumNullValue( Integer.class ) );
162+
assertThat( result.aggregation( sumIntegersAsString ) )
163+
.isEqualTo( TckConfiguration.get().getBackendFeatures().aggregatedSumNullValue( String.class ) );
164+
assertThat( result.aggregation( sumConverted ) )
165+
.isEqualTo( TckConfiguration.get().getBackendFeatures().aggregatedSumNullValue( String.class ) );
166+
assertThat( result.aggregation( sumConvertedNoConversion ) )
167+
.isEqualTo( TckConfiguration.get().getBackendFeatures().aggregatedSumNullValue( Integer.class ) );
168+
assertThat( result.aggregation( sumFiltered ) )
169+
.isEqualTo( TckConfiguration.get().getBackendFeatures().aggregatedSumNullValue( Integer.class ) );
170+
assertThat( result.aggregation( minIntegers ) ).isNull();
171+
assertThat( result.aggregation( minIntegersAsString ) ).isNull();
172+
assertThat( result.aggregation( minConverted ) ).isNull();
173+
assertThat( result.aggregation( maxIntegers ) ).isNull();
174+
assertThat( result.aggregation( maxIntegersAsString ) ).isNull();
175+
assertThat( result.aggregation( maxConverted ) ).isNull();
176+
assertThat( result.aggregation( countIntegers ) ).isEqualTo( 0 );
177+
assertThat( result.aggregation( countConverted ) ).isEqualTo( 0 );
178+
assertThat( result.aggregation( countDistinctIntegers ) ).isEqualTo( 0 );
179+
assertThat( result.aggregation( countDistinctConverted ) ).isEqualTo( 0 );
180+
assertThat( result.aggregation( avgIntegers ) ).isNull();
181+
assertThat( result.aggregation( avgIntegersAsString ) ).isNull();
182+
assertThat( result.aggregation( avgConverted ) ).isNull();
183+
assertThat( result.aggregation( avgIntegersAsDouble ) ).isNull();
184+
assertThat( result.aggregation( avgIntegersAsDoubleRaw ) ).isNull();
185+
assertThat( result.aggregation( avgIntegersAsDoubleFiltered ) ).isNull();
186+
assertThat( result.aggregation( sumDoubles ) )
187+
.isEqualTo( TckConfiguration.get().getBackendFeatures().aggregatedSumNullValue( Double.class ) );
188+
assertThat( result.aggregation( sumDoublesRaw ) )
189+
.isEqualTo( TckConfiguration.get().getBackendFeatures().aggregatedSumNullValue( Double.class ) );
190+
assertThat( result.aggregation( sumFloats ) )
191+
.isEqualTo( TckConfiguration.get().getBackendFeatures().aggregatedSumNullValue( Float.class ) );
192+
assertThat( result.aggregation( sumBigIntegers ) )
193+
.isEqualTo( TckConfiguration.get().getBackendFeatures().aggregatedSumNullValue( BigInteger.class ) );
194+
assertThat( result.aggregation( sumBigDecimals ) )
195+
.isEqualTo( TckConfiguration.get().getBackendFeatures().aggregatedSumNullValue( BigDecimal.class ) );
196+
assertThat( result.aggregation( avgDoubles ) ).isNull();
197+
assertThat( result.aggregation( avgFloats ) ).isNull();
198+
assertThat( result.aggregation( avgBigIntegers ) ).isNull();
199+
assertThat( result.aggregation( avgBigDecimals ) ).isNull();
200+
assertThat( result.aggregation( countDocuments ) ).isEqualTo( 0 );
201+
assertThat( result.aggregation( countValuesIntegerMultiValued ) ).isEqualTo( 0 );
202+
assertThat( result.aggregation( countDistinctValuesIntegerMultiValued ) ).isEqualTo( 0 );
203+
assertThat( result.aggregation( countValuesNestedIntegerMultiValued ) ).isEqualTo( 0 );
204+
assertThat( result.aggregation( countDistinctValuesNestedIntegerMultiValued ) ).isEqualTo( 0 );
205+
assertThat( result.aggregation( sumNestedIntegerMultiValued ) )
206+
.isEqualTo( TckConfiguration.get().getBackendFeatures().aggregatedSumNullValue( Integer.class ) );
207+
assertThat( result.aggregation( rangeWithNested ) ).containsExactly(
208+
entry( Range.canonical( -100, 2 ), List.of( 0L, 0L, 0L ) ),
209+
entry( Range.canonical( 2, 100 ), List.of( 0L, 0L, 0L ) )
210+
);
211+
assertThat( result.aggregation( rangeOnNested ) ).containsExactly(
212+
entry( Range.canonical( -100, 2 ), List.of( 0L, 0L, 0L ) ),
213+
entry( Range.canonical( 2, 100 ), List.of( 0L, 0L, 0L ) )
214+
);
215+
}
216+
151217
@Test
152218
void test_allResults() {
153219
StubMappingScope scope = mainIndex.createScope();
@@ -258,15 +324,17 @@ private SearchQuery<DocumentReference> defineAggregations(
258324
.range( -100, 2 )
259325
.range( 2, 100 )
260326
.value( f.composite()
261-
.from( f.count().documents(), f.count().field( "integer" ),
327+
.from( f.count().documents(),
328+
f.count().field( "integer" ),
262329
f.count().field( "object.nestedIntegerMultiValued" ) )
263330
.asList() ) )
264331
.aggregation(
265332
rangeOnNested, f -> f.range().field( "object.nestedInteger", Integer.class )
266333
.range( -100, 2 )
267334
.range( 2, 100 )
268335
.value( f.composite()
269-
.from( f.count().documents(), f.count().field( "integer" ),
336+
.from( f.count().documents(),
337+
f.count().field( "integer" ),
270338
f.count().field( "object.nestedIntegerMultiValued" ) )
271339
.asList() ) )
272340
.toQuery();
@@ -325,7 +393,8 @@ private static class IndexBinding {
325393
integerMultiValued = root.field( "integerMultiValued", f -> f.asInteger().aggregable( Aggregable.YES ) )
326394
.multiValued().toReference();
327395
converted = root.field( "converted", f -> f.asInteger().aggregable( Aggregable.YES )
328-
.projectionConverter( String.class, (value, context) -> value.toString() ) ).toReference();
396+
.projectionConverter( String.class, (value, context) -> value == null ? null : value.toString() ) )
397+
.toReference();
329398
doubleF = root.field( "doubleF", f -> f.asDouble().aggregable( Aggregable.YES ) ).toReference();
330399
floatF = root.field( "floatF", f -> f.asFloat().aggregable( Aggregable.YES ) ).toReference();
331400
bigInteger = root.field( "bigInteger", f -> f.asBigInteger().decimalScale( 0 ).aggregable( Aggregable.YES ) )

integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/aggregation/MetricTemporalFieldsAggregationsIT.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import java.time.LocalDate;
1010
import java.time.Month;
11+
import java.util.Objects;
1112

1213
import org.hibernate.search.engine.backend.common.DocumentReference;
1314
import org.hibernate.search.engine.backend.document.DocumentElement;
@@ -22,6 +23,7 @@
2223
import org.hibernate.search.engine.search.query.SearchQuery;
2324
import org.hibernate.search.engine.search.query.SearchResult;
2425
import org.hibernate.search.engine.search.query.dsl.SearchQueryOptionsStep;
26+
import org.hibernate.search.integrationtest.backend.tck.testsupport.util.TckConfiguration;
2527
import org.hibernate.search.integrationtest.backend.tck.testsupport.util.extension.SearchSetupHelper;
2628
import org.hibernate.search.util.impl.integrationtest.mapper.stub.BulkIndexer;
2729
import org.hibernate.search.util.impl.integrationtest.mapper.stub.SimpleMappedIndex;
@@ -83,6 +85,35 @@ void test_filteringResults() {
8385
assertThat( result.aggregation( avgConverted ) ).isEqualTo( "2016-12-10" );
8486
}
8587

88+
@Test
89+
void test_filteringNoResults() {
90+
StubMappingScope scope = mainIndex.createScope();
91+
SearchQueryOptionsStep<?, ?, DocumentReference, StubLoadingOptionsStep, ?, ?> options = scope.query()
92+
.where( f -> f.match().field( "style" ).matching( "foobar" ) );
93+
SearchQuery<DocumentReference> query = defineAggregations( options );
94+
95+
SearchResult<DocumentReference> result = query.fetch( 0 );
96+
assertThat( result.aggregation( sumDates ) )
97+
.isEqualTo( TckConfiguration.get().getBackendFeatures().aggregatedSumNullValue( LocalDate.class ) );
98+
assertThat( result.aggregation( sumConverted ) )
99+
.isEqualTo( Objects.toString(
100+
TckConfiguration.get().getBackendFeatures().aggregatedSumNullValue( LocalDate.class ), null ) );
101+
assertThat( result.aggregation( sumConvertedNoConversion ) )
102+
.isEqualTo( TckConfiguration.get().getBackendFeatures().aggregatedSumNullValue( LocalDate.class ) );
103+
assertThat( result.aggregation( sumFiltered ) )
104+
.isEqualTo( TckConfiguration.get().getBackendFeatures().aggregatedSumNullValue( LocalDate.class ) );
105+
assertThat( result.aggregation( minDates ) ).isNull();
106+
assertThat( result.aggregation( minConverted ) ).isNull();
107+
assertThat( result.aggregation( maxDates ) ).isNull();
108+
assertThat( result.aggregation( maxConverted ) ).isNull();
109+
assertThat( result.aggregation( countDates ) ).isEqualTo( 0 );
110+
assertThat( result.aggregation( countConverted ) ).isEqualTo( 0 );
111+
assertThat( result.aggregation( countDistinctDates ) ).isEqualTo( 0 );
112+
assertThat( result.aggregation( countDistinctConverted ) ).isEqualTo( 0 );
113+
assertThat( result.aggregation( avgDates ) ).isNull();
114+
assertThat( result.aggregation( avgConverted ) ).isNull();
115+
}
116+
86117
@Test
87118
void test_allResults() {
88119
StubMappingScope scope = mainIndex.createScope();
@@ -165,7 +196,8 @@ private static class IndexBinding {
165196
IndexBinding(IndexSchemaElement root) {
166197
date = root.field( "date", f -> f.asLocalDate().aggregable( Aggregable.YES ) ).toReference();
167198
converted = root.field( "converted", f -> f.asLocalDate().aggregable( Aggregable.YES )
168-
.projectionConverter( String.class, (value, context) -> value.toString() ) ).toReference();
199+
.projectionConverter( String.class, (value, context) -> value == null ? null : value.toString() ) )
200+
.toReference();
169201
style = root.field( "style", f -> f.asString() ).toReference();
170202

171203
IndexSchemaObjectField nested = root.objectField( "object", ObjectStructure.NESTED );

integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/testsupport/util/TckBackendFeatures.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,8 @@ public <F> boolean rawAggregationProduceSensibleDoubleValue(FieldTypeDescriptor<
222222
public <U, R> R accumulatedNullValue(ProjectionCollector.Provider<U, R> collector) {
223223
return collector.get().empty();
224224
}
225+
226+
public <T> T aggregatedSumNullValue(Class<T> clazz) {
227+
return null;
228+
}
225229
}

lucene-next/backend/lucene/src/main/java/org/hibernate/search/backend/lucene/types/aggregation/impl/AbstractLuceneMetricCompensatedSumAggregation.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ private static class DoubleExtractedValueConverter<E extends Number> extends Ext
124124

125125
@Override
126126
Double convert(E extracted, FromDocumentValueConvertContext context) {
127-
return extracted.doubleValue();
127+
return extracted == null ? null : extracted.doubleValue();
128128
}
129129
}
130130

@@ -137,7 +137,7 @@ private RawExtractedValueConverter(ProjectionConverter<E, T> projectionConverter
137137

138138
@Override
139139
T convert(E extracted, FromDocumentValueConvertContext context) {
140-
return projectionConverter.fromDocumentValue( extracted, context );
140+
return extracted == null ? null : projectionConverter.fromDocumentValue( extracted, context );
141141
}
142142
}
143143

@@ -153,7 +153,7 @@ private DecodingExtractedValueConverter(ProjectionConverter<F, T> projectionConv
153153

154154
@Override
155155
T convert(E extracted, FromDocumentValueConvertContext context) {
156-
return projectionConverter.fromDocumentValue( codec.decode( extracted ), context );
156+
return extracted == null ? null : projectionConverter.fromDocumentValue( codec.decode( extracted ), context );
157157
}
158158
}
159159

0 commit comments

Comments
 (0)