Skip to content

Commit 1af93e1

Browse files
authored
sum of empty histogram is now null (#138378)
Part of #137988 Implement #138349 for the t-digest field type. This changes the behavior of the sum sub-field of t-digest when the digest is empty. Prior to this PR we treated it as 0, and this changes it to be null. This avoids a division by zero error in ESQL when trying to calculate the average of an empty histogram. We are adopting the same behavior for the exponential histogram field (see PR linked above), and this is important to keep the semantics of the two fields as close as possible.
1 parent 6f70507 commit 1af93e1

File tree

3 files changed

+20
-10
lines changed

3 files changed

+20
-10
lines changed

x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/mapper/TDigestFieldMapper.java

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -402,10 +402,13 @@ public void parse(DocumentParserContext context) throws IOException {
402402
);
403403
}
404404
NumericDocValuesField countField = new NumericDocValuesField(valuesCountSubFieldName(fullPath()), parsedTDigest.count());
405-
NumericDocValuesField sumField = new NumericDocValuesField(
406-
valuesSumSubFieldName(fullPath()),
407-
NumericUtils.doubleToSortableLong(parsedTDigest.sum())
408-
);
405+
NumericDocValuesField sumField = null;
406+
if (Double.isNaN(parsedTDigest.sum()) == false) {
407+
sumField = new NumericDocValuesField(
408+
valuesSumSubFieldName(fullPath()),
409+
NumericUtils.doubleToSortableLong(parsedTDigest.sum())
410+
);
411+
}
409412
if (context.doc().getByKey(fieldType().name()) != null) {
410413
throw new IllegalArgumentException(
411414
"Field ["
@@ -417,7 +420,9 @@ public void parse(DocumentParserContext context) throws IOException {
417420
}
418421
context.doc().addWithKey(fieldType().name(), digestField);
419422
context.doc().add(countField);
420-
context.doc().add(sumField);
423+
if (sumField != null) {
424+
context.doc().add(sumField);
425+
}
421426
if (maxField != null) {
422427
context.doc().add(maxField);
423428
}
@@ -564,8 +569,12 @@ public DocValuesLoader docValuesLoader(LeafReader leafReader, int[] docIdsInLeaf
564569
max = Double.NaN;
565570
}
566571

567-
sumValues.advanceExact(docId);
568-
sum = NumericUtils.sortableLongToDouble(sumValues.longValue());
572+
if (sumValues != null) {
573+
sumValues.advanceExact(docId);
574+
sum = NumericUtils.sortableLongToDouble(sumValues.longValue());
575+
} else {
576+
sum = Double.NaN;
577+
}
569578

570579
binaryValue = docValues.binaryValue();
571580
return true;
@@ -595,7 +604,9 @@ public void write(XContentBuilder b) throws IOException {
595604
if (Double.isNaN(max) == false) {
596605
b.field("max", max);
597606
}
598-
b.field("sum", sum);
607+
if (Double.isNaN(sum) == false) {
608+
b.field("sum", sum);
609+
}
599610

600611
b.startArray(CENTROIDS_NAME);
601612
while (value.next()) {

x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/mapper/TDigestParser.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ public static ParsedTDigest parse(String mappedFieldName, XContentParser parser)
158158
);
159159
}
160160
if (centroids.isEmpty()) {
161-
sum = 0.0;
161+
sum = null;
162162
min = null;
163163
max = null;
164164
}

x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/analytics/t_digest_fieldtype.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,6 @@ TDigest with synthetic source and empty digest:
276276
- match:
277277
_source:
278278
latency:
279-
sum: 0.0
280279
centroids: [ ]
281280
counts: [ ]
282281

0 commit comments

Comments
 (0)