This is an automated email from the ASF dual-hosted git repository.
gian pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/master by this push:
new f82463dcc43 fix: spectatorHistogram null handling (#18122)
f82463dcc43 is described below
commit f82463dcc437f9c458c7546716d7ca4d91c5eaf1
Author: Hiroshi Fukada <[email protected]>
AuthorDate: Tue Oct 28 11:40:24 2025 -0400
fix: spectatorHistogram null handling (#18122)
---
...SpectatorHistogramPercentilePostAggregator.java | 3 +
...pectatorHistogramPercentilesPostAggregator.java | 3 +
.../SpectatorHistogramAggregatorTest.java | 101 +++++++++++++++++++++
3 files changed, 107 insertions(+)
diff --git
a/extensions-contrib/spectator-histogram/src/main/java/org/apache/druid/spectator/histogram/SpectatorHistogramPercentilePostAggregator.java
b/extensions-contrib/spectator-histogram/src/main/java/org/apache/druid/spectator/histogram/SpectatorHistogramPercentilePostAggregator.java
index 80854c57d46..29da04c67cc 100644
---
a/extensions-contrib/spectator-histogram/src/main/java/org/apache/druid/spectator/histogram/SpectatorHistogramPercentilePostAggregator.java
+++
b/extensions-contrib/spectator-histogram/src/main/java/org/apache/druid/spectator/histogram/SpectatorHistogramPercentilePostAggregator.java
@@ -90,6 +90,9 @@ public class SpectatorHistogramPercentilePostAggregator
implements PostAggregato
public Object compute(final Map<String, Object> combinedAggregators)
{
final SpectatorHistogram sketch = (SpectatorHistogram)
field.compute(combinedAggregators);
+ if (sketch == null) {
+ return null;
+ }
return sketch.getPercentileValue(percentile);
}
diff --git
a/extensions-contrib/spectator-histogram/src/main/java/org/apache/druid/spectator/histogram/SpectatorHistogramPercentilesPostAggregator.java
b/extensions-contrib/spectator-histogram/src/main/java/org/apache/druid/spectator/histogram/SpectatorHistogramPercentilesPostAggregator.java
index ae6d9392644..51370d9038c 100644
---
a/extensions-contrib/spectator-histogram/src/main/java/org/apache/druid/spectator/histogram/SpectatorHistogramPercentilesPostAggregator.java
+++
b/extensions-contrib/spectator-histogram/src/main/java/org/apache/druid/spectator/histogram/SpectatorHistogramPercentilesPostAggregator.java
@@ -86,6 +86,9 @@ public class SpectatorHistogramPercentilesPostAggregator
implements PostAggregat
public Object compute(final Map<String, Object> combinedAggregators)
{
final SpectatorHistogram sketch = (SpectatorHistogram)
field.compute(combinedAggregators);
+ if (sketch == null) {
+ return null;
+ }
return sketch.getPercentileValues(percentiles);
}
diff --git
a/extensions-contrib/spectator-histogram/src/test/java/org/apache/druid/spectator/histogram/SpectatorHistogramAggregatorTest.java
b/extensions-contrib/spectator-histogram/src/test/java/org/apache/druid/spectator/histogram/SpectatorHistogramAggregatorTest.java
index 88e710645d1..15979b94376 100644
---
a/extensions-contrib/spectator-histogram/src/test/java/org/apache/druid/spectator/histogram/SpectatorHistogramAggregatorTest.java
+++
b/extensions-contrib/spectator-histogram/src/test/java/org/apache/druid/spectator/histogram/SpectatorHistogramAggregatorTest.java
@@ -783,6 +783,107 @@ public class SpectatorHistogramAggregatorTest extends
InitializedNullHandlingTes
Assert.assertEquals(n * segments.size(), (Double) results.get(0).get(1),
0.001);
}
+ @Test
+ public void testPercentilePostAggregatorWithNullSketch() throws Exception
+ {
+ Sequence<ResultRow> seq = helper.createIndexAndRunQueryOnSegment(
+ new
File(this.getClass().getClassLoader().getResource("input_data.tsv").getFile()),
+ INPUT_DATA_PARSE_SPEC,
+ String.join(
+ "\n",
+ "[",
+ " {\"type\": \"spectatorHistogram\", \"name\": \"histogram\",
\"fieldName\": \"cost\"}",
+ "]"
+ ),
+ 0, // minTimestamp
+ Granularities.NONE,
+ 10, // maxRowCount
+ String.join(
+ "\n",
+ "{",
+ " \"queryType\": \"groupBy\",",
+ " \"dataSource\": \"test_datasource\",",
+ " \"granularity\": \"ALL\",",
+ " \"dimensions\": [\"product\"],",
+ " \"aggregations\": [",
+ " {\"type\": \"spectatorHistogram\", \"name\":
\"merged_histogram\", \"fieldName\": "
+ + "\"histogram\"}",
+ " ],",
+ " \"postAggregations\": [",
+ " {\"type\": \"percentileSpectatorHistogram\", \"name\":
\"p50\", \"field\": {\"type\": \"fieldAccess\",\"fieldName\":
\"merged_histogram\"}"
+ + ", \"percentile\": \"50.0\"}",
+ " ],",
+ " \"intervals\":
[\"2016-01-01T00:00:00.000Z/2016-01-31T00:00:00.000Z\"]",
+ "}"
+ )
+ );
+
+ List<ResultRow> results = seq.toList();
+ Assert.assertEquals(6, results.size());
+
+ // First three rows should have valid histograms and percentile values
+ Assert.assertNotNull("Row [0] should have non-null percentile",
results.get(0).get(2));
+ Assert.assertNotNull("Row [1] should have non-null percentile",
results.get(1).get(2));
+ Assert.assertNotNull("Row [2] should have non-null percentile",
results.get(2).get(2));
+
+ // Last three rows have null histograms, so percentile should also be null
+ Assert.assertNull("Row [3] should have null percentile when histogram is
null", results.get(3).get(2));
+ Assert.assertNull("Row [4] should have null percentile when histogram is
null", results.get(4).get(2));
+ Assert.assertNull("Row [5] should have null percentile when histogram is
null", results.get(5).get(2));
+ }
+
+ @Test
+ public void testPercentilesPostAggregatorWithNullSketch() throws Exception
+ {
+ Sequence<ResultRow> seq = helper.createIndexAndRunQueryOnSegment(
+ new
File(this.getClass().getClassLoader().getResource("input_data.tsv").getFile()),
+ INPUT_DATA_PARSE_SPEC,
+ String.join(
+ "\n",
+ "[",
+ " {\"type\": \"spectatorHistogram\", \"name\": \"histogram\",
\"fieldName\": \"cost\"}",
+ "]"
+ ),
+ 0, // minTimestamp
+ Granularities.NONE,
+ 10, // maxRowCount
+ String.join(
+ "\n",
+ "{",
+ " \"queryType\": \"groupBy\",",
+ " \"dataSource\": \"test_datasource\",",
+ " \"granularity\": \"ALL\",",
+ " \"dimensions\": [\"product\"],",
+ " \"aggregations\": [",
+ " {\"type\": \"spectatorHistogram\", \"name\":
\"merged_histogram\", \"fieldName\": "
+ + "\"histogram\"}",
+ " ],",
+ " \"postAggregations\": [",
+ " {\"type\": \"percentilesSpectatorHistogram\", \"name\":
\"percentiles\", \"field\": {\"type\": \"fieldAccess\",\"fieldName\":
\"merged_histogram\"}"
+ + ", \"percentiles\": [25.0, 50.0, 75.0]}",
+ " ],",
+ " \"intervals\":
[\"2016-01-01T00:00:00.000Z/2016-01-31T00:00:00.000Z\"]",
+ "}"
+ )
+ );
+
+ List<ResultRow> results = seq.toList();
+ Assert.assertEquals(6, results.size());
+
+ // First three rows should have valid histograms and percentiles arrays
+ Assert.assertNotNull("Row [0] should have non-null percentiles array",
results.get(0).get(2));
+ Assert.assertTrue("Row [0] percentiles should be double array",
results.get(0).get(2) instanceof double[]);
+ Assert.assertNotNull("Row [1] should have non-null percentiles array",
results.get(1).get(2));
+ Assert.assertTrue("Row [1] percentiles should be double array",
results.get(1).get(2) instanceof double[]);
+ Assert.assertNotNull("Row [2] should have non-null percentiles array",
results.get(2).get(2));
+ Assert.assertTrue("Row [2] percentiles should be double array",
results.get(2).get(2) instanceof double[]);
+
+ // Last three rows have null histograms, so percentiles should also be null
+ Assert.assertNull("Row [3] should have null percentiles when histogram is
null", results.get(3).get(2));
+ Assert.assertNull("Row [4] should have null percentiles when histogram is
null", results.get(4).get(2));
+ Assert.assertNull("Row [5] should have null percentiles when histogram is
null", results.get(5).get(2));
+ }
+
private static void assertResultsMatch(List<ResultRow> results, int rowNum,
String expectedProduct)
{
ResultRow row = results.get(rowNum);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]