This is an automated email from the ASF dual-hosted git repository.
rongr 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 ff2a33318e [multistage] add cast function (#9384)
ff2a33318e is described below
commit ff2a33318edf9669daeb23184c29dd595c8b654e
Author: Rong Rong <[email protected]>
AuthorDate: Tue Sep 13 11:42:17 2022 -0700
[multistage] add cast function (#9384)
* add CAST by using the DataConversion func
Co-authored-by: Rong Rong <[email protected]>
---
.../pinot/query/planner/logical/RexExpression.java | 43 +++++++++++++++++++++-
.../query/runtime/QueryRunnerExceptionTest.java | 7 ++--
.../pinot/query/runtime/QueryRunnerTest.java | 9 ++++-
3 files changed, 53 insertions(+), 6 deletions(-)
diff --git
a/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/RexExpression.java
b/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/RexExpression.java
index d9b04ec06f..32a3608c86 100644
---
a/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/RexExpression.java
+++
b/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/RexExpression.java
@@ -18,6 +18,7 @@
*/
package org.apache.pinot.query.planner.logical;
+import com.google.common.base.Preconditions;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;
@@ -30,6 +31,7 @@ import org.apache.calcite.rex.RexNode;
import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.util.NlsString;
+import org.apache.pinot.common.utils.PinotDataType;
import org.apache.pinot.query.planner.serde.ProtoProperties;
import org.apache.pinot.spi.data.FieldSpec;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -56,13 +58,50 @@ public interface RexExpression {
RexCall rexCall = (RexCall) rexNode;
List<RexExpression> operands =
rexCall.getOperands().stream().map(RexExpression::toRexExpression)
.collect(Collectors.toList());
- return new RexExpression.FunctionCall(rexCall.getKind(),
toDataType(rexCall.getType()),
- rexCall.getOperator().getName(), operands);
+ return toRexExpression(rexCall, operands);
} else {
throw new IllegalArgumentException("Unsupported RexNode type with
SqlKind: " + rexNode.getKind());
}
}
+ static RexExpression toRexExpression(RexCall rexCall, List<RexExpression>
operands) {
+ switch (rexCall.getKind()) {
+ case CAST:
+ // CAST is being rewritten into "rexCall.CAST<targetType>(inputValue)",
+ // - e.g. result type has already been converted into the CAST
RexCall, so we assert single operand.
+ Preconditions.checkState(operands.size() == 1, "CAST takes exactly 2
arguments");
+ RelDataType castType = rexCall.getType();
+ // add the 2nd argument as the source type info.
+ operands.add(new Literal(FieldSpec.DataType.STRING,
rexCall.getOperands().get(0).getType().getSqlTypeName(),
+ toPinotDataType(rexCall.getOperands().get(0).getType()).name()));
+ return new RexExpression.FunctionCall(rexCall.getKind(),
toDataType(rexCall.getType()), "CAST", operands);
+ default:
+ return new RexExpression.FunctionCall(rexCall.getKind(),
toDataType(rexCall.getType()),
+ rexCall.getOperator().getName(), operands);
+ }
+ }
+
+ static PinotDataType toPinotDataType(RelDataType type) {
+ switch (type.getSqlTypeName()) {
+ case INTEGER:
+ return PinotDataType.INTEGER;
+ case BIGINT:
+ return PinotDataType.LONG;
+ case FLOAT:
+ return PinotDataType.FLOAT;
+ case DOUBLE:
+ return PinotDataType.DOUBLE;
+ case CHAR:
+ case VARCHAR:
+ return PinotDataType.STRING;
+ case BOOLEAN:
+ return PinotDataType.BOOLEAN;
+ default:
+ // TODO: do not assume byte type.
+ return PinotDataType.BYTES;
+ }
+ }
+
static RexExpression toRexExpression(AggregateCall aggCall) {
List<RexExpression> operands =
aggCall.getArgList().stream().map(InputRef::new).collect(Collectors.toList());
return new RexExpression.FunctionCall(aggCall.getAggregation().getKind(),
toDataType(aggCall.getType()),
diff --git
a/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/QueryRunnerExceptionTest.java
b/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/QueryRunnerExceptionTest.java
index de70190b7f..5b5c084ce5 100644
---
a/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/QueryRunnerExceptionTest.java
+++
b/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/QueryRunnerExceptionTest.java
@@ -68,9 +68,10 @@ public class QueryRunnerExceptionTest extends
QueryRunnerTestBase {
@DataProvider(name = "testDataWithSqlExecutionExceptions")
private Object[][] provideTestSqlWithExecutionException() {
return new Object[][] {
- // default planner will auto-cast string column to numeric on JOIN
condition, so exception is:
- // "error while invoking cast function", because the cast cannot be
done.
- new Object[]{"SELECT a.col2 - b.col3 FROM a JOIN b ON a.col1 =
b.col1", "transform function: cast"},
+ // Function with incorrect argument signature should throw runtime
exception
+ new Object[]{"SELECT least(a.col2, b.col3) FROM a JOIN b ON a.col1 =
b.col1",
+ "ArithmeticFunctions.least(double,double) with arguments"},
+ // Function that tries to cast String to Number should throw runtime
exception
new Object[]{"SELECT a.col2, b.col1 FROM a JOIN b ON a.col1 = b.col3",
"transform function: cast"},
};
}
diff --git
a/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/QueryRunnerTest.java
b/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/QueryRunnerTest.java
index 8e5167b007..7ae65076b8 100644
---
a/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/QueryRunnerTest.java
+++
b/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/QueryRunnerTest.java
@@ -183,7 +183,14 @@ public class QueryRunnerTest extends QueryRunnerTestBase {
new Object[]{"SELECT dateTrunc('DAY', round(a.ts, b.ts)) FROM a JOIN b
"
+ "ON a.col1 = b.col1 AND a.col2 = b.col2", 15},
- // Distinct value done via GROUP BY with empty expr aggregation list.
+ // Test CAST
+ // - implicit CAST
+ new Object[]{"SELECT a.col1, a.col2, AVG(a.col3) FROM a GROUP BY
a.col1, a.col2", 5},
+ // - explicit CAST
+ new Object[]{"SELECT a.col1, dateTrunc('DAY', CAST(SUM(a.col3) AS
BIGINT)) FROM a GROUP BY a.col1", 5},
+
+ // Test DISTINCT
+ // - distinct value done via GROUP BY with empty expr aggregation
list.
new Object[]{"SELECT a.col2, a.col3 FROM a JOIN b ON a.col1 = b.col1 "
+ " WHERE b.col3 > 0 GROUP BY a.col2, a.col3", 5},
};
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]