use of com.facebook.presto.spi.plan.FilterNode in project presto by prestodb.
the class ImplementFilteredAggregations method apply.
@Override
public Result apply(AggregationNode aggregation, Captures captures, Context context) {
Assignments.Builder newAssignments = Assignments.builder();
ImmutableMap.Builder<VariableReferenceExpression, Aggregation> aggregations = ImmutableMap.builder();
ImmutableList.Builder<Expression> maskSymbols = ImmutableList.builder();
boolean aggregateWithoutFilterPresent = false;
for (Map.Entry<VariableReferenceExpression, Aggregation> entry : aggregation.getAggregations().entrySet()) {
VariableReferenceExpression output = entry.getKey();
// strip the filters
Optional<VariableReferenceExpression> mask = entry.getValue().getMask();
if (entry.getValue().getFilter().isPresent()) {
// TODO remove cast once assignment can be RowExpression
Expression filter = OriginalExpressionUtils.castToExpression(entry.getValue().getFilter().get());
VariableReferenceExpression variable = context.getVariableAllocator().newVariable(filter, BOOLEAN);
verify(!mask.isPresent(), "Expected aggregation without mask symbols, see Rule pattern");
newAssignments.put(variable, castToRowExpression(filter));
mask = Optional.of(variable);
maskSymbols.add(createSymbolReference(variable));
} else {
aggregateWithoutFilterPresent = true;
}
aggregations.put(output, new Aggregation(entry.getValue().getCall(), Optional.empty(), entry.getValue().getOrderBy(), entry.getValue().isDistinct(), mask));
}
Expression predicate = TRUE_LITERAL;
if (!aggregation.hasNonEmptyGroupingSet() && !aggregateWithoutFilterPresent) {
predicate = combineDisjunctsWithDefault(maskSymbols.build(), TRUE_LITERAL);
}
// identity projection for all existing inputs
newAssignments.putAll(identitiesAsSymbolReferences(aggregation.getSource().getOutputVariables()));
return Result.ofPlanNode(new AggregationNode(aggregation.getSourceLocation(), context.getIdAllocator().getNextId(), new FilterNode(aggregation.getSourceLocation(), context.getIdAllocator().getNextId(), new ProjectNode(context.getIdAllocator().getNextId(), aggregation.getSource(), newAssignments.build()), castToRowExpression(predicate)), aggregations.build(), aggregation.getGroupingSets(), ImmutableList.of(), aggregation.getStep(), aggregation.getHashVariable(), aggregation.getGroupIdVariable()));
}
use of com.facebook.presto.spi.plan.FilterNode in project presto by prestodb.
the class RewriteFilterWithExternalFunctionToProject method apply.
@Override
public Result apply(FilterNode node, Captures captures, Context context) {
if (!node.getPredicate().accept(new ExternalCallExpressionChecker(functionAndTypeManager), null)) {
// No remote function in predicate
return Result.empty();
}
VariableReferenceExpression predicateVariable = context.getVariableAllocator().newVariable(node.getPredicate());
Assignments.Builder assignments = Assignments.builder();
node.getOutputVariables().forEach(variable -> assignments.put(variable, variable));
Assignments identityAssignments = assignments.build();
assignments.put(predicateVariable, node.getPredicate());
return Result.ofPlanNode(new ProjectNode(node.getSourceLocation(), context.getIdAllocator().getNextId(), new FilterNode(node.getSourceLocation(), context.getIdAllocator().getNextId(), new ProjectNode(context.getIdAllocator().getNextId(), node.getSource(), assignments.build()), predicateVariable), identityAssignments, LOCAL));
}
use of com.facebook.presto.spi.plan.FilterNode in project presto by prestodb.
the class TestRuleIndex method testWithPlanNodeHierarchy.
@Test
public void testWithPlanNodeHierarchy() {
Rule projectRule1 = new NoOpRule(Pattern.typeOf(ProjectNode.class));
Rule projectRule2 = new NoOpRule(Pattern.typeOf(ProjectNode.class));
Rule filterRule = new NoOpRule(Pattern.typeOf(FilterNode.class));
Rule anyRule = new NoOpRule(Pattern.any());
RuleIndex ruleIndex = RuleIndex.builder().register(projectRule1).register(projectRule2).register(filterRule).register(anyRule).build();
ProjectNode projectNode = planBuilder.project(Assignments.of(), planBuilder.values());
FilterNode filterNode = planBuilder.filter(BooleanLiteral.TRUE_LITERAL, planBuilder.values());
ValuesNode valuesNode = planBuilder.values();
assertEquals(ruleIndex.getCandidates(projectNode).collect(toSet()), ImmutableSet.of(projectRule1, projectRule2, anyRule));
assertEquals(ruleIndex.getCandidates(filterNode).collect(toSet()), ImmutableSet.of(filterRule, anyRule));
assertEquals(ruleIndex.getCandidates(valuesNode).collect(toSet()), ImmutableSet.of(anyRule));
}
use of com.facebook.presto.spi.plan.FilterNode in project presto by prestodb.
the class SimpleFilterProjectSemiJoinStatsRule method calculate.
private Optional<PlanNodeStatsEstimate> calculate(FilterNode filterNode, SemiJoinNode semiJoinNode, StatsProvider statsProvider, Session session, TypeProvider types) {
PlanNodeStatsEstimate sourceStats = statsProvider.getStats(semiJoinNode.getSource());
PlanNodeStatsEstimate filteringSourceStats = statsProvider.getStats(semiJoinNode.getFilteringSource());
VariableReferenceExpression filteringSourceJoinVariable = semiJoinNode.getFilteringSourceJoinVariable();
VariableReferenceExpression sourceJoinVariable = semiJoinNode.getSourceJoinVariable();
Optional<SemiJoinOutputFilter> semiJoinOutputFilter;
VariableReferenceExpression semiJoinOutput = semiJoinNode.getSemiJoinOutput();
if (isExpression(filterNode.getPredicate())) {
semiJoinOutputFilter = extractSemiJoinOutputFilter(castToExpression(filterNode.getPredicate()), semiJoinOutput);
} else {
semiJoinOutputFilter = extractSemiJoinOutputFilter(filterNode.getPredicate(), semiJoinOutput);
}
if (!semiJoinOutputFilter.isPresent()) {
return Optional.empty();
}
PlanNodeStatsEstimate semiJoinStats;
if (semiJoinOutputFilter.get().isNegated()) {
semiJoinStats = computeAntiJoin(sourceStats, filteringSourceStats, sourceJoinVariable, filteringSourceJoinVariable);
} else {
semiJoinStats = computeSemiJoin(sourceStats, filteringSourceStats, sourceJoinVariable, filteringSourceJoinVariable);
}
if (semiJoinStats.isOutputRowCountUnknown()) {
return Optional.of(PlanNodeStatsEstimate.unknown());
}
// apply remaining predicate
PlanNodeStatsEstimate filteredStats;
if (isExpression(filterNode.getPredicate())) {
filteredStats = filterStatsCalculator.filterStats(semiJoinStats, castToExpression(semiJoinOutputFilter.get().getRemainingPredicate()), session, types);
} else {
filteredStats = filterStatsCalculator.filterStats(semiJoinStats, semiJoinOutputFilter.get().getRemainingPredicate(), session);
}
if (filteredStats.isOutputRowCountUnknown()) {
return Optional.of(semiJoinStats.mapOutputRowCount(rowCount -> rowCount * UNKNOWN_FILTER_COEFFICIENT));
}
return Optional.of(filteredStats);
}
use of com.facebook.presto.spi.plan.FilterNode in project presto by prestodb.
the class DynamicFilterMatcher method match.
private MatchResult match(FilterNode filterNode, Session session, Metadata metadata, SymbolAliases symbolAliases) {
checkState(this.filterNode == null, "filterNode must be null at this point");
this.filterNode = filterNode;
this.symbolAliases = symbolAliases;
LogicalRowExpressions logicalRowExpressions = new LogicalRowExpressions(new RowExpressionDeterminismEvaluator(metadata.getFunctionAndTypeManager()), new FunctionResolution(metadata.getFunctionAndTypeManager()), metadata.getFunctionAndTypeManager());
boolean staticFilterMatches = expectedStaticFilter.map(filter -> {
RowExpressionVerifier verifier = new RowExpressionVerifier(symbolAliases, metadata, session);
RowExpression staticFilter = logicalRowExpressions.combineConjuncts(extractDynamicFilters(filterNode.getPredicate()).getStaticConjuncts());
return verifier.process(filter, staticFilter);
}).orElse(true);
return new MatchResult(match() && staticFilterMatches);
}
Aggregations