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 73f2c924e26 Fix two VectorAggregator null checks. (#19086)
73f2c924e26 is described below

commit 73f2c924e2655bd72abafab190ae98fbf9be8b4f
Author: Gian Merlino <[email protected]>
AuthorDate: Fri Mar 6 12:18:40 2026 -0800

    Fix two VectorAggregator null checks. (#19086)
    
    Fixes two bugs in ApproximateHistogramVectorAggregator and
    DoubleMeanVectorAggregator.
    
    When "rows" is nonnull, we need to use it to index into the null
    vector and data vector. The prior code was using it for the
    data vector, but not the null vector.
---
 .../ApproximateHistogramVectorAggregator.java      |  5 +++--
 .../ApproximateHistogramVectorAggregatorTest.java  | 26 ++++++++++++++++++++++
 .../mean/DoubleMeanVectorAggregator.java           | 16 +++++--------
 3 files changed, 34 insertions(+), 13 deletions(-)

diff --git 
a/extensions-core/histogram/src/main/java/org/apache/druid/query/aggregation/histogram/ApproximateHistogramVectorAggregator.java
 
b/extensions-core/histogram/src/main/java/org/apache/druid/query/aggregation/histogram/ApproximateHistogramVectorAggregator.java
index 728271f89d6..245296961c6 100644
--- 
a/extensions-core/histogram/src/main/java/org/apache/druid/query/aggregation/histogram/ApproximateHistogramVectorAggregator.java
+++ 
b/extensions-core/histogram/src/main/java/org/apache/druid/query/aggregation/histogram/ApproximateHistogramVectorAggregator.java
@@ -75,11 +75,12 @@ public class ApproximateHistogramVectorAggregator 
implements VectorAggregator
     final boolean[] isValueNull = selector.getNullVector();
 
     for (int i = 0; i < numRows; i++) {
-      if (isValueNull != null && isValueNull[i]) {
+      final int row = rows != null ? rows[i] : i;
+      if (isValueNull != null && isValueNull[row]) {
         continue;
       }
       final int position = positions[i] + positionOffset;
-      innerAggregator.aggregate(buf, position, vector[rows != null ? rows[i] : 
i]);
+      innerAggregator.aggregate(buf, position, vector[row]);
     }
   }
 
diff --git 
a/extensions-core/histogram/src/test/java/org/apache/druid/query/aggregation/histogram/ApproximateHistogramVectorAggregatorTest.java
 
b/extensions-core/histogram/src/test/java/org/apache/druid/query/aggregation/histogram/ApproximateHistogramVectorAggregatorTest.java
index 51bcb1ec61e..501559ae59f 100644
--- 
a/extensions-core/histogram/src/test/java/org/apache/druid/query/aggregation/histogram/ApproximateHistogramVectorAggregatorTest.java
+++ 
b/extensions-core/histogram/src/test/java/org/apache/druid/query/aggregation/histogram/ApproximateHistogramVectorAggregatorTest.java
@@ -121,6 +121,32 @@ public class ApproximateHistogramVectorAggregatorTest
 
   }
 
+  @Test
+  public void testAggregateMultiPositionsWithNullsAndRowsIndirection()
+  {
+    // field_1 has a null vector where index 10 is null (value 45).
+    // By using rows indirection to map loop index 0 -> row 10, we verify the 
null check
+    // correctly skips the null row.
+    ApproximateHistogramAggregatorFactory factory = 
buildHistogramAggFactory("field_1");
+    final int size = factory.getMaxIntermediateSize();
+    ByteBuffer byteBuffer = ByteBuffer.allocate(size * 2);
+    VectorAggregator vectorAggregator = 
factory.factorizeVector(vectorColumnSelectorFactory);
+    final int[] positions = new int[]{0, size};
+    vectorAggregator.init(byteBuffer, positions[0]);
+    vectorAggregator.init(byteBuffer, positions[1]);
+
+    // rows[0]=10 (null row, value 45), rows[1]=0 (non-null, value 23)
+    // Position 0 should skip the null; position 1 should get value 23.
+    vectorAggregator.aggregate(byteBuffer, 2, positions, new int[]{10, 0}, 0);
+
+    ApproximateHistogram h0 = (ApproximateHistogram) 
vectorAggregator.get(byteBuffer, 0);
+    Assert.assertEquals(0, h0.count());
+
+    ApproximateHistogram h1 = (ApproximateHistogram) 
vectorAggregator.get(byteBuffer, size);
+    Assert.assertArrayEquals(new float[]{23}, h1.positions(), 0.1f);
+    Assert.assertArrayEquals(new long[]{1}, h1.bins());
+  }
+
   @Test
   public void testAggregateMultiPositions()
   {
diff --git 
a/processing/src/main/java/org/apache/druid/query/aggregation/mean/DoubleMeanVectorAggregator.java
 
b/processing/src/main/java/org/apache/druid/query/aggregation/mean/DoubleMeanVectorAggregator.java
index b8858b9aa75..1a81adaf811 100644
--- 
a/processing/src/main/java/org/apache/druid/query/aggregation/mean/DoubleMeanVectorAggregator.java
+++ 
b/processing/src/main/java/org/apache/druid/query/aggregation/mean/DoubleMeanVectorAggregator.java
@@ -73,18 +73,12 @@ public class DoubleMeanVectorAggregator implements 
VectorAggregator
     final double[] vector = selector.getDoubleVector();
     final boolean[] nulls = selector.getNullVector();
 
-    if (nulls != null) {
-      for (int j = 0; j < numRows; j++) {
-        if (!nulls[j]) {
-          final double val = vector[rows != null ? rows[j] : j];
-          DoubleMeanHolder.update(buf, positions[j] + positionOffset, val);
-        }
-      }
-    } else {
-      for (int i = 0; i < numRows; i++) {
-        final double val = vector[rows != null ? rows[i] : i];
-        DoubleMeanHolder.update(buf, positions[i] + positionOffset, val);
+    for (int i = 0; i < numRows; i++) {
+      final int row = rows != null ? rows[i] : i;
+      if (nulls != null && nulls[row]) {
+        continue;
       }
+      DoubleMeanHolder.update(buf, positions[i] + positionOffset, vector[row]);
     }
   }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to