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

jackie 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 2e1e475697 Skip computation incase of Null Literal for case/when 
transformation (#11444)
2e1e475697 is described below

commit 2e1e4756977e272572cce7b53df9902de6167686
Author: Abhishek Sharma <abhishek.sha...@spothero.com>
AuthorDate: Tue Aug 29 13:20:03 2023 -0400

    Skip computation incase of Null Literal for case/when transformation 
(#11444)
---
 .../transform/function/CaseTransformFunction.java  | 25 ++++++++++++++++------
 .../function/LiteralTransformFunction.java         |  4 ++++
 .../function/LiteralTransformFunctionTest.java     | 19 ++++++++++++++++
 .../src/test/resources/queries/Case.json           |  5 +++++
 4 files changed, 47 insertions(+), 6 deletions(-)

diff --git 
a/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/CaseTransformFunction.java
 
b/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/CaseTransformFunction.java
index f4ff9330b3..aff6b460c9 100644
--- 
a/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/CaseTransformFunction.java
+++ 
b/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/CaseTransformFunction.java
@@ -113,7 +113,7 @@ public class CaseTransformFunction extends 
ComputeDifferentlyWhenNullHandlingEna
       _whenStatements.add(arguments.get(i * 2));
       _thenStatements.add(arguments.get(i * 2 + 1));
     }
-    if (arguments.size() % 2 != 0) {
+    if (arguments.size() % 2 != 0 && 
!isNullLiteralTransformation(arguments.get(arguments.size() - 1))) {
       _elseStatement = arguments.get(arguments.size() - 1);
     }
   }
@@ -128,16 +128,21 @@ public class CaseTransformFunction extends 
ComputeDifferentlyWhenNullHandlingEna
     for (int i = numWhenStatements; i < numWhenStatements * 2; i++) {
       _thenStatements.add(arguments.get(i));
     }
-    if (arguments.size() % 2 != 0) {
+    if (arguments.size() % 2 != 0 && 
!isNullLiteralTransformation(arguments.get(arguments.size() - 1))) {
       _elseStatement = arguments.get(arguments.size() - 1);
     }
   }
 
   private TransformResultMetadata calculateResultMetadata() {
-    TransformResultMetadata elseStatementResultMetadata = 
_elseStatement.getResultMetadata();
-    DataType dataType = elseStatementResultMetadata.getDataType();
-    Preconditions.checkState(elseStatementResultMetadata.isSingleValue(),
-        "Unsupported multi-value expression in the ELSE clause");
+    DataType dataType;
+    if (_elseStatement == null) {
+      dataType = DataType.UNKNOWN;
+    } else {
+      TransformResultMetadata elseStatementResultMetadata = 
_elseStatement.getResultMetadata();
+      dataType = elseStatementResultMetadata.getDataType();
+      Preconditions.checkState(elseStatementResultMetadata.isSingleValue(),
+          "Unsupported multi-value expression in the ELSE clause");
+    }
     int numThenStatements = _thenStatements.size();
     for (int i = 0; i < numThenStatements; i++) {
       TransformFunction thenStatement = _thenStatements.get(i);
@@ -257,6 +262,14 @@ public class CaseTransformFunction extends 
ComputeDifferentlyWhenNullHandlingEna
     return _resultMetadata;
   }
 
+  private boolean isNullLiteralTransformation(TransformFunction function) {
+    if (function instanceof LiteralTransformFunction) {
+      LiteralTransformFunction literalFunction = (LiteralTransformFunction) 
function;
+      return literalFunction.isNull();
+    }
+    return false;
+  }
+
   /**
    * Evaluate the ValueBlock for the WHEN statements, returns an array with 
the index(1 to N) of matched WHEN clause -1
    * means there is no match.
diff --git 
a/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/LiteralTransformFunction.java
 
b/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/LiteralTransformFunction.java
index ec9f010101..3ce9abba8b 100644
--- 
a/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/LiteralTransformFunction.java
+++ 
b/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/LiteralTransformFunction.java
@@ -269,4 +269,8 @@ public class LiteralTransformFunction implements 
TransformFunction {
     bitmap.add(0L, length);
     return bitmap;
   }
+
+  public boolean isNull() {
+    return _dataType == DataType.UNKNOWN;
+  }
 }
diff --git 
a/pinot-core/src/test/java/org/apache/pinot/core/operator/transform/function/LiteralTransformFunctionTest.java
 
b/pinot-core/src/test/java/org/apache/pinot/core/operator/transform/function/LiteralTransformFunctionTest.java
index b1d7d55343..d6f4060e80 100644
--- 
a/pinot-core/src/test/java/org/apache/pinot/core/operator/transform/function/LiteralTransformFunctionTest.java
+++ 
b/pinot-core/src/test/java/org/apache/pinot/core/operator/transform/function/LiteralTransformFunctionTest.java
@@ -78,4 +78,23 @@ public class LiteralTransformFunctionTest {
     }
     Assert.assertEquals(nullLiteral.getNullBitmap(_projectionBlock), 
expectedBitmap);
   }
+
+  @Test
+  public void testIsNullLiteralTransform() {
+    LiteralTransformFunction nullLiteral =
+        new LiteralTransformFunction(new LiteralContext(DataType.UNKNOWN, 
null));
+    Assert.assertTrue(nullLiteral.isNull());
+
+    LiteralTransformFunction nullLiteralWITHBooleanValue =
+        new LiteralTransformFunction(new LiteralContext(DataType.UNKNOWN, 
true));
+    Assert.assertTrue(nullLiteralWITHBooleanValue.isNull());
+
+    LiteralTransformFunction trueLiteral =
+        new LiteralTransformFunction(new LiteralContext(DataType.BOOLEAN, 
true));
+    Assert.assertFalse(trueLiteral.isNull());
+
+    LiteralTransformFunction stringNullLiteral =
+        new LiteralTransformFunction(new LiteralContext(DataType.STRING, 
null));
+    Assert.assertFalse(stringNullLiteral.isNull());
+  }
 }
diff --git a/pinot-query-runtime/src/test/resources/queries/Case.json 
b/pinot-query-runtime/src/test/resources/queries/Case.json
index 4375d1b482..196997f4a7 100644
--- a/pinot-query-runtime/src/test/resources/queries/Case.json
+++ b/pinot-query-runtime/src/test/resources/queries/Case.json
@@ -21,13 +21,18 @@
     "queries": [
       { "sql": "SELECT intCol, CASE WHEN boolCol = true THEN 'Yes' ELSE 'No' 
END AS boolVal, strCol FROM {tbl1}"},
       { "sql": "SELECT intCol, CASE WHEN boolCol = true THEN 'Yes' END AS 
boolVal, strCol FROM {tbl1}"},
+      { "sql": "SELECT intCol, CASE WHEN boolCol = true THEN 'Yes' ELSE NULL 
END AS boolVal, strCol FROM {tbl1}"},
       { "sql": "SELECT intCol, CASE WHEN intCol % 2 = 0 THEN intCol END AS 
intVal, strCol FROM {tbl1}"},
+      { "sql": "SELECT intCol, CASE WHEN intCol % 2 = 0 THEN intCol ELSE NULL 
END AS intVal, strCol FROM {tbl1}"},
       { "sql": "SELECT intCol, CASE WHEN longCol % 2 = 0 THEN longCol END AS 
longVal, strCol FROM {tbl1}"},
+      { "sql": "SELECT intCol, CASE WHEN longCol % 2 = 0 THEN longCol ELSE 
NULL END AS longVal, strCol FROM {tbl1}"},
       { "sql": "SELECT intCol, CASE WHEN longCol % 2 = 0 THEN longCol ELSE 
longCol * 2 END AS longVal, strCol FROM {tbl1}"},
       { "sql": "SELECT intCol, CASE WHEN doubleCol % 2.343 = 0 THEN doubleCol 
END AS doubleVal, strCol FROM {tbl1}"},
+      { "sql": "SELECT intCol, CASE WHEN doubleCol % 2.343 = 0 THEN doubleCol 
ELSE NULL END AS doubleVal, strCol FROM {tbl1}"},
       { "sql": "SELECT intCol, CASE WHEN doubleCol % 2.343 = 0 THEN doubleCol 
ELSE doubleCol * 2 END AS doubleVal, strCol FROM {tbl1}"},
       { "sql": "SELECT intCol, CASE WHEN intCol % 2 = 0 THEN intCol ELSE 
intCol * 4 END AS intVal, strCol FROM {tbl1}"},
       { "sql": "SELECT intCol, CASE WHEN floatCol > 4.0 THEN floatCol END AS 
floatVal, strCol FROM {tbl1}"},
+      { "sql": "SELECT intCol, CASE WHEN floatCol > 4.0 THEN floatCol ELSE 
NULL END AS floatVal, strCol FROM {tbl1}"},
       { "sql": "SELECT intCol, CASE WHEN floatCol > 4.0 THEN floatCol ELSE 
floatCol * 4 END AS floatVal, strCol FROM {tbl1}"},
       { "sql": "SELECT intCol, CASE WHEN strCol = 'one' THEN strCol END AS 
strVal FROM {tbl1}"},
       { "sql": "SELECT intCol, CASE WHEN strCol = 'one' THEN strCol ELSE 'TWO' 
END AS strVal FROM {tbl1}"},


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

Reply via email to