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