This is an automated email from the ASF dual-hosted git repository.
jackietien pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new b63c4aba78 [IOTDB-4010] Use FilterAndProjectOperator for query that
does not contain non-mappable UDF (#6929)
b63c4aba78 is described below
commit b63c4aba78355c908af332579372dd6ae4dba2e1
Author: Liao Lanyu <[email protected]>
AuthorDate: Wed Aug 10 09:14:24 2022 +0800
[IOTDB-4010] Use FilterAndProjectOperator for query that does not contain
non-mappable UDF (#6929)
---
.../operator/process/FilterAndProjectOperator.java | 11 ++++-
.../plan/expression/multi/FunctionExpression.java | 3 ++
.../db/mpp/plan/planner/OperatorTreeGenerator.java | 56 +++++++++++++++++++++-
3 files changed, 68 insertions(+), 2 deletions(-)
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/FilterAndProjectOperator.java
b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/FilterAndProjectOperator.java
index 0b6bf595fc..60dc07b2f2 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/FilterAndProjectOperator.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/FilterAndProjectOperator.java
@@ -56,6 +56,9 @@ public class FilterAndProjectOperator implements
ProcessOperator {
private final OperatorContext operatorContext;
+ // false when we only need to do projection
+ private final boolean hasFilter;
+
public FilterAndProjectOperator(
OperatorContext operatorContext,
Operator inputOperator,
@@ -65,7 +68,8 @@ public class FilterAndProjectOperator implements
ProcessOperator {
List<ColumnTransformer> commonTransformerList,
List<LeafColumnTransformer> projectLeafColumnTransformerList,
List<ColumnTransformer> projectOutputTransformerList,
- boolean hasNonMappableUDF) {
+ boolean hasNonMappableUDF,
+ boolean hasFilter) {
this.operatorContext = operatorContext;
this.inputOperator = inputOperator;
this.filterLeafColumnTransformerList = filterLeafColumnTransformerList;
@@ -75,6 +79,7 @@ public class FilterAndProjectOperator implements
ProcessOperator {
this.projectOutputTransformerList = projectOutputTransformerList;
this.hasNonMappableUDF = hasNonMappableUDF;
this.filterTsBlockBuilder = new TsBlockBuilder(8, filterOutputDataTypes);
+ this.hasFilter = hasFilter;
}
@Override
@@ -89,6 +94,10 @@ public class FilterAndProjectOperator implements
ProcessOperator {
return null;
}
+ if (!hasFilter) {
+ return getTransformedTsBlock(input);
+ }
+
TsBlock filterResult = getFilterTsBlock(input);
// contains non-mappable udf, we leave calculation for TransformOperator
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/multi/FunctionExpression.java
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/multi/FunctionExpression.java
index 049381ede7..2371300cff 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/multi/FunctionExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/multi/FunctionExpression.java
@@ -431,6 +431,9 @@ public class FunctionExpression extends Expression {
@Override
public boolean isMappable(TypeProvider typeProvider) {
+ if (isBuiltInAggregationFunctionExpression) {
+ return false;
+ }
return new UDTFInformationInferrer(functionName)
.getAccessStrategy(
expressions.stream().map(Expression::toString).collect(Collectors.toList()),
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/OperatorTreeGenerator.java
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/OperatorTreeGenerator.java
index c67c3bfd6d..5c4570a1fe 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/OperatorTreeGenerator.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/OperatorTreeGenerator.java
@@ -796,9 +796,62 @@ public class OperatorTreeGenerator extends
PlanVisitor<Operator, LocalExecutionP
final Operator inputOperator = generateOnlyChildOperator(node, context);
final List<TSDataType> inputDataTypes = getInputColumnTypes(node,
context.getTypeProvider());
final Map<String, List<InputLocation>> inputLocations = makeLayout(node);
+ final Expression[] projectExpressions = node.getOutputExpressions();
+ final TypeProvider typeProvider = context.getTypeProvider();
context.getTimeSliceAllocator().recordExecutionWeight(operatorContext, 1);
+ boolean hasNonMappableUDF = false;
+ for (Expression expression : projectExpressions) {
+ if (!expression.isMappable(typeProvider)) {
+ hasNonMappableUDF = true;
+ break;
+ }
+ }
+
+ // Use FilterAndProject Operator when project expressions are all mappable
+ if (!hasNonMappableUDF) {
+ // init project UDTFContext
+ UDTFContext projectContext = new UDTFContext(node.getZoneId());
+ projectContext.constructUdfExecutors(projectExpressions);
+
+ List<ColumnTransformer> projectOutputTransformerList = new ArrayList<>();
+ Map<Expression, ColumnTransformer> projectExpressionColumnTransformerMap
= new HashMap<>();
+
+ // records LeafColumnTransformer of project expressions
+ List<LeafColumnTransformer> projectLeafColumnTransformerList = new
ArrayList<>();
+
+ ColumnTransformerVisitor visitor = new ColumnTransformerVisitor();
+ ColumnTransformerVisitor.ColumnTransformerVisitorContext
projectColumnTransformerContext =
+ new ColumnTransformerVisitor.ColumnTransformerVisitorContext(
+ projectContext,
+ typeProvider,
+ projectLeafColumnTransformerList,
+ inputLocations,
+ projectExpressionColumnTransformerMap,
+ ImmutableMap.of(),
+ ImmutableList.of(),
+ inputDataTypes,
+ inputLocations.size());
+
+ for (Expression expression : projectExpressions) {
+ projectOutputTransformerList.add(
+ visitor.process(expression, projectColumnTransformerContext));
+ }
+
+ return new FilterAndProjectOperator(
+ operatorContext,
+ inputOperator,
+ inputDataTypes,
+ ImmutableList.of(),
+ null,
+ ImmutableList.of(),
+ projectLeafColumnTransformerList,
+ projectOutputTransformerList,
+ false,
+ false);
+ }
+
try {
return new TransformOperator(
operatorContext,
@@ -918,7 +971,8 @@ public class OperatorTreeGenerator extends
PlanVisitor<Operator, LocalExecutionP
commonTransformerList,
projectLeafColumnTransformerList,
projectOutputTransformerList,
- hasNonMappableUDF);
+ hasNonMappableUDF,
+ true);
// Project expressions don't contain Non-Mappable UDF, TransformOperator
is not needed
if (!hasNonMappableUDF) {