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 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]