This is an automated email from the ASF dual-hosted git repository.

gortiz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git


The following commit(s) were added to refs/heads/master by this push:
     new 3be9fbe1590 Guard against NPE for MSE filtered aggregations (#17386)
3be9fbe1590 is described below

commit 3be9fbe159060e504f0258a57b1e49c7b7b6e65e
Author: Yash Mayya <[email protected]>
AuthorDate: Wed Dec 17 02:55:38 2025 -0800

    Guard against NPE for MSE filtered aggregations (#17386)
    
    * Guard against NPE for MSE filtered aggregations
    
    * Add unit test
---
 .../query/runtime/operator/AggregateOperator.java  |  4 +++-
 .../runtime/operator/AggregateOperatorTest.java    | 28 ++++++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git 
a/pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/operator/AggregateOperator.java
 
b/pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/operator/AggregateOperator.java
index e0268362766..dfc1cc3600a 100644
--- 
a/pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/operator/AggregateOperator.java
+++ 
b/pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/operator/AggregateOperator.java
@@ -351,7 +351,9 @@ public class AggregateOperator extends MultiStageOperator {
       List<Object[]> rows = block.asRowHeap().getRows();
       int numRows = rows.size();
       for (int rowId = 0; rowId < numRows; rowId++) {
-        if ((int) rows.get(rowId)[filterArgId] == 1) {
+        // Treat NULL filter values as non-matching (SQL WHERE clause 
semantics).
+        Object filterValue = rows.get(rowId)[filterArgId];
+        if (filterValue != null && (int) filterValue == 1) {
           matchedBitmap.add(rowId);
         }
       }
diff --git 
a/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/operator/AggregateOperatorTest.java
 
b/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/operator/AggregateOperatorTest.java
index 4e12c3d20f2..c96805a1a15 100644
--- 
a/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/operator/AggregateOperatorTest.java
+++ 
b/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/operator/AggregateOperatorTest.java
@@ -185,6 +185,34 @@ public class AggregateOperatorTest {
     assertTrue(operator.nextBlock().isSuccess(), "Second block is EOS (done 
processing)");
   }
 
+  @Test
+  public void testFilteredAggregateWithNullValues() {
+    // Given:
+    List<RexExpression.FunctionCall> aggCalls =
+        List.of(getSum(new RexExpression.InputRef(1)), getSum(new 
RexExpression.InputRef(1)));
+    List<Integer> filterArgs = List.of(-1, 2);
+    List<Integer> groupKeys = List.of(0);
+    DataSchema inSchema =
+        new DataSchema(new String[]{"group", "arg", "filterArg"}, new 
ColumnDataType[]{INT, DOUBLE, BOOLEAN});
+    // null for the filterArg should be treated as false
+    when(_input.nextBlock()).thenReturn(
+            OperatorTestUtil.block(inSchema, new Object[]{2, 1.0, null}, new 
Object[]{2, 2.0, 1}))
+        .thenReturn(OperatorTestUtil.block(inSchema, new Object[]{2, 3.0, 1}))
+        .thenReturn(SuccessMseBlock.INSTANCE);
+    DataSchema resultSchema =
+        new DataSchema(new String[]{"group", "sum", "sumWithFilter"}, new 
ColumnDataType[]{INT, DOUBLE, DOUBLE});
+    AggregateOperator operator = getOperator(resultSchema, aggCalls, 
filterArgs, groupKeys);
+
+    // When:
+    List<Object[]> resultRows = ((MseBlock.Data) 
operator.nextBlock()).asRowHeap().getRows();
+
+    // Then:
+    assertEquals(resultRows.size(), 1);
+    assertEquals(resultRows.get(0), new Object[]{2, 6.0, 5.0},
+        "Expected three columns (group by key, agg value, agg value with 
filter), agg value is final result");
+    assertTrue(operator.nextBlock().isSuccess(), "Second block is EOS (done 
processing)");
+  }
+
   @Test
   public void testGroupByAggregateWithHashCollision() {
     _input = OperatorTestUtil.getOperator(OperatorTestUtil.OP_1);


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

Reply via email to