This is an automated email from the ASF dual-hosted git repository. gortiz 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 4588d0b15d Modify AggregationPlanNode to consider not nullable columns that do not contain nulls (#14342) 4588d0b15d is described below commit 4588d0b15db53553f25615d9ec2d552173143b8a Author: Gonzalo Ortiz Jaureguizar <gor...@users.noreply.github.com> AuthorDate: Fri Nov 8 15:39:18 2024 +0100 Modify AggregationPlanNode to consider not nullable columns that do not contain nulls (#14342) --- .../pinot/core/plan/AggregationPlanNode.java | 40 ++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/pinot-core/src/main/java/org/apache/pinot/core/plan/AggregationPlanNode.java b/pinot-core/src/main/java/org/apache/pinot/core/plan/AggregationPlanNode.java index 2a1321f1b9..6202f0890d 100644 --- a/pinot-core/src/main/java/org/apache/pinot/core/plan/AggregationPlanNode.java +++ b/pinot-core/src/main/java/org/apache/pinot/core/plan/AggregationPlanNode.java @@ -36,6 +36,7 @@ import org.apache.pinot.segment.spi.AggregationFunctionType; import org.apache.pinot.segment.spi.IndexSegment; import org.apache.pinot.segment.spi.SegmentContext; import org.apache.pinot.segment.spi.datasource.DataSource; +import org.apache.pinot.segment.spi.index.reader.NullValueVectorReader; import static org.apache.pinot.segment.spi.AggregationFunctionType.*; @@ -94,7 +95,8 @@ public class AggregationPlanNode implements PlanNode { FilterPlanNode filterPlanNode = new FilterPlanNode(_segmentContext, _queryContext); BaseFilterOperator filterOperator = filterPlanNode.run(); - if (!_queryContext.isNullHandlingEnabled()) { + boolean hasNullValues = _queryContext.isNullHandlingEnabled() && hasNullValues(aggregationFunctions); + if (!hasNullValues) { if (canOptimizeFilteredCount(filterOperator, aggregationFunctions)) { return new FastFilteredCountOperator(_queryContext, filterOperator, _indexSegment.getSegmentMetadata()); } @@ -118,17 +120,49 @@ public class AggregationPlanNode implements PlanNode { return new AggregationOperator(_queryContext, aggregationInfo, numTotalDocs); } + /** + * Returns {@code true} if any of the aggregation functions have null values, {@code false} otherwise. + * + * The current implementation is pessimistic and returns {@code true} if any of the arguments to the aggregation + * functions is of function type. This is because we do not have a way to determine if the function will return null + * values without actually evaluating it. + */ + private boolean hasNullValues(AggregationFunction[] aggregationFunctions) { + for (AggregationFunction<?, ?> aggregationFunction : aggregationFunctions) { + for (ExpressionContext argument : aggregationFunction.getInputExpressions()) { + switch (argument.getType()) { + case IDENTIFIER: + DataSource dataSource = _indexSegment.getDataSource(argument.getIdentifier()); + NullValueVectorReader nullValueVector = dataSource.getNullValueVector(); + if (nullValueVector != null && !nullValueVector.getNullBitmap().isEmpty()) { + return true; + } + break; + case LITERAL: + if (argument.getLiteral().isNull()) { + return true; + } + break; + case FUNCTION: + default: + return true; + } + } + } + return false; + } + /** * Returns {@code true} if the given aggregations can be solved with dictionary or column metadata, {@code false} * otherwise. */ private static boolean isFitForNonScanBasedPlan(AggregationFunction[] aggregationFunctions, IndexSegment indexSegment) { - for (AggregationFunction aggregationFunction : aggregationFunctions) { + for (AggregationFunction<?, ?> aggregationFunction : aggregationFunctions) { if (aggregationFunction.getType() == COUNT) { continue; } - ExpressionContext argument = (ExpressionContext) aggregationFunction.getInputExpressions().get(0); + ExpressionContext argument = aggregationFunction.getInputExpressions().get(0); if (argument.getType() != ExpressionContext.Type.IDENTIFIER) { return false; } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@pinot.apache.org For additional commands, e-mail: commits-h...@pinot.apache.org