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

yashmayya 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 845829112f Handle null values appropriately for AND / OR / NOT in 
InbuiltFunctionEvaluator (#16229)
845829112f is described below

commit 845829112ff53de1aef052a1b56fd4fe27596882
Author: Yash Mayya <yash.ma...@gmail.com>
AuthorDate: Wed Jul 2 19:37:04 2025 +0530

    Handle null values appropriately for AND / OR / NOT in 
InbuiltFunctionEvaluator (#16229)
---
 .../local/function/InbuiltFunctionEvaluator.java   | 50 ++++++++++++++---
 .../function/InbuiltFunctionEvaluatorTest.java     | 62 ++++++++++++++++++++++
 2 files changed, 106 insertions(+), 6 deletions(-)

diff --git 
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/function/InbuiltFunctionEvaluator.java
 
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/function/InbuiltFunctionEvaluator.java
index d39380292c..86ff0254b5 100644
--- 
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/function/InbuiltFunctionEvaluator.java
+++ 
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/function/InbuiltFunctionEvaluator.java
@@ -141,12 +141,22 @@ public class InbuiltFunctionEvaluator implements 
FunctionEvaluator {
 
     @Override
     public Object execute(GenericRow row) {
-      return !((Boolean) _argumentNode.execute(row));
+      Boolean res = (Boolean) _argumentNode.execute(row);
+      if (res == null) {
+        return null;
+      } else {
+        return !res;
+      }
     }
 
     @Override
     public Object execute(Object[] values) {
-      return !((Boolean) _argumentNode.execute(values));
+      Boolean res = (Boolean) _argumentNode.execute(values);
+      if (res == null) {
+        return null;
+      } else {
+        return !res;
+      }
     }
   }
 
@@ -159,24 +169,38 @@ public class InbuiltFunctionEvaluator implements 
FunctionEvaluator {
 
     @Override
     public Object execute(GenericRow row) {
+      boolean hasNull = false;
+
       for (ExecutableNode executableNode : _argumentNodes) {
         Boolean res = (Boolean) executableNode.execute(row);
+        if (res == null) {
+          hasNull = true;
+          continue;
+        }
         if (res) {
           return true;
         }
       }
-      return false;
+
+      return hasNull ? null : false;
     }
 
     @Override
     public Object execute(Object[] values) {
+      boolean hasNull = false;
+
       for (ExecutableNode executableNode : _argumentNodes) {
         Boolean res = (Boolean) executableNode.execute(values);
+        if (res == null) {
+          hasNull = true;
+          continue;
+        }
         if (res) {
           return true;
         }
       }
-      return false;
+
+      return hasNull ? null : false;
     }
   }
 
@@ -189,24 +213,38 @@ public class InbuiltFunctionEvaluator implements 
FunctionEvaluator {
 
     @Override
     public Object execute(GenericRow row) {
+      boolean hasNull = false;
+
       for (ExecutableNode executableNode : _argumentNodes) {
         Boolean res = (Boolean) executableNode.execute(row);
+        if (res == null) {
+          hasNull = true;
+          continue;
+        }
         if (!res) {
           return false;
         }
       }
-      return true;
+
+      return hasNull ? null : true;
     }
 
     @Override
     public Object execute(Object[] values) {
+      boolean hasNull = false;
+
       for (ExecutableNode executableNode : _argumentNodes) {
         Boolean res = (Boolean) executableNode.execute(values);
+        if (res == null) {
+          hasNull = true;
+          continue;
+        }
         if (!res) {
           return false;
         }
       }
-      return true;
+
+      return hasNull ? null : true;
     }
   }
 
diff --git 
a/pinot-segment-local/src/test/java/org/apache/pinot/segment/local/function/InbuiltFunctionEvaluatorTest.java
 
b/pinot-segment-local/src/test/java/org/apache/pinot/segment/local/function/InbuiltFunctionEvaluatorTest.java
index e9bb5f235f..a1539372c3 100644
--- 
a/pinot-segment-local/src/test/java/org/apache/pinot/segment/local/function/InbuiltFunctionEvaluatorTest.java
+++ 
b/pinot-segment-local/src/test/java/org/apache/pinot/segment/local/function/InbuiltFunctionEvaluatorTest.java
@@ -25,6 +25,7 @@ import org.testng.annotations.Test;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
 
 
 public class InbuiltFunctionEvaluatorTest {
@@ -39,6 +40,67 @@ public class InbuiltFunctionEvaluatorTest {
     checkBooleanLiteralExpression("0", 0);
   }
 
+  @Test
+  public void testOrWithNulls() {
+    InbuiltFunctionEvaluator evaluator = new 
InbuiltFunctionEvaluator("or(null, false, true)");
+    Object output = evaluator.evaluate(new GenericRow());
+    assertEquals(output, true);
+
+    evaluator = new InbuiltFunctionEvaluator("or(null, false, null)");
+    output = evaluator.evaluate(new GenericRow());
+    assertNull(output);
+
+    evaluator = new InbuiltFunctionEvaluator("or(null, null, null)");
+    output = evaluator.evaluate(new Object[]{});
+    assertNull(output);
+
+    evaluator = new InbuiltFunctionEvaluator("or(null, true, null)");
+    output = evaluator.evaluate(new Object[]{});
+    assertEquals(output, true);
+
+    evaluator = new InbuiltFunctionEvaluator("or(true, false)");
+    output = evaluator.evaluate(new GenericRow());
+    assertEquals(output, true);
+  }
+
+  @Test
+  public void testAndWithNulls() {
+    InbuiltFunctionEvaluator evaluator = new 
InbuiltFunctionEvaluator("and(null, false, true)");
+    Object output = evaluator.evaluate(new GenericRow());
+    assertEquals(output, false);
+
+    evaluator = new InbuiltFunctionEvaluator("and(null, false, null)");
+    output = evaluator.evaluate(new GenericRow());
+    assertEquals(output, false);
+
+    evaluator = new InbuiltFunctionEvaluator("and(null, null, null)");
+    output = evaluator.evaluate(new Object[]{});
+    assertNull(output);
+
+    evaluator = new InbuiltFunctionEvaluator("and(null, true, null)");
+    output = evaluator.evaluate(new Object[]{});
+    assertNull(output);
+
+    evaluator = new InbuiltFunctionEvaluator("and(true, false)");
+    output = evaluator.evaluate(new GenericRow());
+    assertEquals(output, false);
+  }
+
+  @Test
+  public void testNotWithNulls() {
+    InbuiltFunctionEvaluator evaluator = new 
InbuiltFunctionEvaluator("not(null)");
+    Object output = evaluator.evaluate(new GenericRow());
+    assertNull(output);
+
+    evaluator = new InbuiltFunctionEvaluator("not(false)");
+    output = evaluator.evaluate(new Object[]{});
+    assertEquals(output, true);
+
+    evaluator = new InbuiltFunctionEvaluator("not(true)");
+    output = evaluator.evaluate(new GenericRow());
+    assertEquals(output, false);
+  }
+
   private void checkBooleanLiteralExpression(String expression, int value) {
     InbuiltFunctionEvaluator evaluator = new 
InbuiltFunctionEvaluator(expression);
     Object output = evaluator.evaluate(new GenericRow());


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@pinot.apache.org
For additional commands, e-mail: commits-h...@pinot.apache.org

Reply via email to