use of com.facebook.presto.spi.plan.PlanNode in project presto by prestodb.
the class TransformExistsApplyToLateralNode method apply.
@Override
public Result apply(ApplyNode parent, Captures captures, Context context) {
if (parent.getSubqueryAssignments().size() != 1) {
return Result.empty();
}
Expression expression = castToExpression(getOnlyElement(parent.getSubqueryAssignments().getExpressions()));
if (!(expression instanceof ExistsPredicate)) {
return Result.empty();
}
Optional<PlanNode> nonDefaultAggregation = rewriteToNonDefaultAggregation(parent, context);
return nonDefaultAggregation.map(Result::ofPlanNode).orElseGet(() -> Result.ofPlanNode(rewriteToDefaultAggregation(parent, context)));
}
use of com.facebook.presto.spi.plan.PlanNode in project presto by prestodb.
the class TransformCorrelatedInPredicateToJoin method apply.
private Result apply(ApplyNode apply, InPredicate inPredicate, VariableReferenceExpression inPredicateOutputVariable, Lookup lookup, PlanNodeIdAllocator idAllocator, PlanVariableAllocator variableAllocator) {
Optional<Decorrelated> decorrelated = new DecorrelatingVisitor(lookup, apply.getCorrelation(), variableAllocator.getTypes()).decorrelate(apply.getSubquery());
if (!decorrelated.isPresent()) {
return Result.empty();
}
PlanNode projection = buildInPredicateEquivalent(apply, inPredicate, inPredicateOutputVariable, decorrelated.get(), idAllocator, variableAllocator);
return Result.ofPlanNode(projection);
}
use of com.facebook.presto.spi.plan.PlanNode in project presto by prestodb.
the class TransformCorrelatedInPredicateToJoin method buildInPredicateEquivalent.
private PlanNode buildInPredicateEquivalent(ApplyNode apply, InPredicate inPredicate, VariableReferenceExpression inPredicateOutputVariable, Decorrelated decorrelated, PlanNodeIdAllocator idAllocator, PlanVariableAllocator variableAllocator) {
Expression correlationCondition = and(decorrelated.getCorrelatedPredicates());
PlanNode decorrelatedBuildSource = decorrelated.getDecorrelatedNode();
AssignUniqueId probeSide = new AssignUniqueId(apply.getSourceLocation(), idAllocator.getNextId(), apply.getInput(), variableAllocator.newVariable("unique", BIGINT));
VariableReferenceExpression buildSideKnownNonNull = variableAllocator.newVariable(inPredicateOutputVariable.getSourceLocation(), "buildSideKnownNonNull", BIGINT);
ProjectNode buildSide = new ProjectNode(idAllocator.getNextId(), decorrelatedBuildSource, Assignments.builder().putAll(identitiesAsSymbolReferences(decorrelatedBuildSource.getOutputVariables())).put(buildSideKnownNonNull, castToRowExpression(bigint(0))).build());
checkArgument(inPredicate.getValue() instanceof SymbolReference, "Unexpected expression: %s", inPredicate.getValue());
SymbolReference probeSideSymbolReference = (SymbolReference) inPredicate.getValue();
checkArgument(inPredicate.getValueList() instanceof SymbolReference, "Unexpected expression: %s", inPredicate.getValueList());
SymbolReference buildSideSymbolReference = (SymbolReference) inPredicate.getValueList();
Expression joinExpression = and(or(new IsNullPredicate(probeSideSymbolReference), new ComparisonExpression(ComparisonExpression.Operator.EQUAL, probeSideSymbolReference, buildSideSymbolReference), new IsNullPredicate(buildSideSymbolReference)), correlationCondition);
JoinNode leftOuterJoin = leftOuterJoin(idAllocator, probeSide, buildSide, joinExpression);
VariableReferenceExpression countMatchesVariable = variableAllocator.newVariable(getSourceLocation(buildSideSymbolReference.getLocation()), "countMatches", BIGINT);
VariableReferenceExpression countNullMatchesVariable = variableAllocator.newVariable(getSourceLocation(buildSideSymbolReference.getLocation()), "countNullMatches", BIGINT);
Expression matchCondition = and(new IsNotNullPredicate(probeSideSymbolReference), new IsNotNullPredicate(buildSideSymbolReference));
Expression nullMatchCondition = and(new IsNotNullPredicate(createSymbolReference(buildSideKnownNonNull)), new NotExpression(matchCondition));
AggregationNode aggregation = new AggregationNode(apply.getSourceLocation(), idAllocator.getNextId(), leftOuterJoin, ImmutableMap.<VariableReferenceExpression, AggregationNode.Aggregation>builder().put(countMatchesVariable, countWithFilter(matchCondition)).put(countNullMatchesVariable, countWithFilter(nullMatchCondition)).build(), singleGroupingSet(probeSide.getOutputVariables()), ImmutableList.of(), AggregationNode.Step.SINGLE, Optional.empty(), Optional.empty());
// TODO since we care only about "some count > 0", we could have specialized node instead of leftOuterJoin that does the job without materializing join results
SearchedCaseExpression inPredicateEquivalent = new SearchedCaseExpression(ImmutableList.of(new WhenClause(isGreaterThan(countMatchesVariable, 0), booleanConstant(true)), new WhenClause(isGreaterThan(countNullMatchesVariable, 0), booleanConstant(null))), Optional.of(booleanConstant(false)));
return new ProjectNode(idAllocator.getNextId(), aggregation, Assignments.builder().putAll(identitiesAsSymbolReferences(apply.getInput().getOutputVariables())).put(inPredicateOutputVariable, castToRowExpression(inPredicateEquivalent)).build());
}
use of com.facebook.presto.spi.plan.PlanNode in project presto by prestodb.
the class TransformCorrelatedScalarAggregationToJoin method apply.
@Override
public Result apply(LateralJoinNode lateralJoinNode, Captures captures, Context context) {
PlanNode subquery = lateralJoinNode.getSubquery();
if (!isScalar(subquery, context.getLookup())) {
return Result.empty();
}
Optional<AggregationNode> aggregation = findAggregation(subquery, context.getLookup());
if (!(aggregation.isPresent() && aggregation.get().getGroupingKeys().isEmpty())) {
return Result.empty();
}
ScalarAggregationToJoinRewriter rewriter = new ScalarAggregationToJoinRewriter(functionAndTypeManager, context.getVariableAllocator(), context.getIdAllocator(), context.getLookup());
PlanNode rewrittenNode = rewriter.rewriteScalarAggregation(lateralJoinNode, aggregation.get());
if (rewrittenNode instanceof LateralJoinNode) {
return Result.empty();
}
return Result.ofPlanNode(rewrittenNode);
}
use of com.facebook.presto.spi.plan.PlanNode in project presto by prestodb.
the class PushTopNThroughUnion method apply.
@Override
public Result apply(TopNNode topNNode, Captures captures, Context context) {
UnionNode unionNode = captures.get(CHILD);
ImmutableList.Builder<PlanNode> sources = ImmutableList.builder();
for (PlanNode source : unionNode.getSources()) {
SymbolMapper.Builder symbolMapper = SymbolMapper.builder();
Set<VariableReferenceExpression> sourceOutputVariables = ImmutableSet.copyOf(source.getOutputVariables());
for (VariableReferenceExpression unionOutput : unionNode.getOutputVariables()) {
Set<VariableReferenceExpression> inputVariables = ImmutableSet.copyOf(unionNode.getVariableMapping().get(unionOutput));
VariableReferenceExpression unionInput = getLast(intersection(inputVariables, sourceOutputVariables));
symbolMapper.put(unionOutput, unionInput);
}
sources.add(symbolMapper.build().map(topNNode, source, context.getIdAllocator().getNextId()));
}
return Result.ofPlanNode(new UnionNode(unionNode.getSourceLocation(), unionNode.getId(), sources.build(), unionNode.getOutputVariables(), unionNode.getVariableMapping()));
}
Aggregations