return new ApplyNode(node.getId(), input, subquery, subqueryAssignments.build(), newCorrelation, node.getOriginSubquery());
return new ApplyNode(node.getId(), input, subquery, subqueryAssignments.build(), newCorrelation, node.getOriginSubquery());
@Override public PlanNode visitApply(ApplyNode node, RewriteContext<Void> context) { PlanNode source = context.rewrite(node.getInput()); PlanNode subquery = context.rewrite(node.getSubquery()); List<Symbol> canonicalCorrelation = Lists.transform(node.getCorrelation(), this::canonicalize); return new ApplyNode(node.getId(), source, subquery, canonicalize(node.getSubqueryAssignments()), canonicalCorrelation, node.getOriginSubquery()); }
@Override public PlanNode visitApply(ApplyNode node, RewriteContext<Void> context) { PlanNode source = context.rewrite(node.getInput()); PlanNode subquery = context.rewrite(node.getSubquery()); List<Symbol> canonicalCorrelation = Lists.transform(node.getCorrelation(), this::canonicalize); return new ApplyNode(node.getId(), source, subquery, canonicalize(node.getSubqueryAssignments()), canonicalCorrelation, node.getOriginSubquery()); }
@Override public PlanNode optimize(PlanNode plan, Session session, TypeProvider types, SymbolAllocator symbolAllocator, PlanNodeIdAllocator idAllocator, WarningCollector warningCollector) { searchFrom(plan).where(ApplyNode.class::isInstance) .findFirst() .ifPresent(node -> { ApplyNode applyNode = (ApplyNode) node; throw error(applyNode.getCorrelation(), applyNode.getOriginSubquery()); }); searchFrom(plan).where(LateralJoinNode.class::isInstance) .findFirst() .ifPresent(node -> { LateralJoinNode lateralJoinNode = (LateralJoinNode) node; throw error(lateralJoinNode.getCorrelation(), lateralJoinNode.getOriginSubquery()); }); return plan; }
@Override public PlanNode optimize(PlanNode plan, Session session, TypeProvider types, SymbolAllocator symbolAllocator, PlanNodeIdAllocator idAllocator, WarningCollector warningCollector) { searchFrom(plan).where(ApplyNode.class::isInstance) .findFirst() .ifPresent(node -> { ApplyNode applyNode = (ApplyNode) node; throw error(applyNode.getCorrelation(), applyNode.getOriginSubquery()); }); searchFrom(plan).where(LateralJoinNode.class::isInstance) .findFirst() .ifPresent(node -> { LateralJoinNode lateralJoinNode = (LateralJoinNode) node; throw error(lateralJoinNode.getCorrelation(), lateralJoinNode.getOriginSubquery()); }); return plan; }
node.getCorrelation(), LateralJoinNode.Type.INNER, node.getOriginSubquery());
node.getCorrelation(), LateralJoinNode.Type.INNER, node.getOriginSubquery());
private Optional<PlanNode> rewriteToNonDefaultAggregation(ApplyNode applyNode, Context context) { checkState(applyNode.getSubquery().getOutputSymbols().isEmpty(), "Expected subquery output symbols to be pruned"); Symbol exists = getOnlyElement(applyNode.getSubqueryAssignments().getSymbols()); Symbol subqueryTrue = context.getSymbolAllocator().newSymbol("subqueryTrue", BOOLEAN); Assignments.Builder assignments = Assignments.builder(); assignments.putIdentities(applyNode.getInput().getOutputSymbols()); assignments.put(exists, new CoalesceExpression(ImmutableList.of(subqueryTrue.toSymbolReference(), BooleanLiteral.FALSE_LITERAL))); PlanNode subquery = new ProjectNode( context.getIdAllocator().getNextId(), new LimitNode( context.getIdAllocator().getNextId(), applyNode.getSubquery(), 1L, false), Assignments.of(subqueryTrue, TRUE_LITERAL)); PlanNodeDecorrelator decorrelator = new PlanNodeDecorrelator(context.getIdAllocator(), context.getLookup()); if (!decorrelator.decorrelateFilters(subquery, applyNode.getCorrelation()).isPresent()) { return Optional.empty(); } return Optional.of(new ProjectNode(context.getIdAllocator().getNextId(), new LateralJoinNode( applyNode.getId(), applyNode.getInput(), subquery, applyNode.getCorrelation(), LEFT, applyNode.getOriginSubquery()), assignments.build())); }
private PlanNode rewriteToDefaultAggregation(ApplyNode parent, Context context) { Symbol count = context.getSymbolAllocator().newSymbol(COUNT.toString(), BIGINT); Symbol exists = getOnlyElement(parent.getSubqueryAssignments().getSymbols()); return new LateralJoinNode( parent.getId(), parent.getInput(), new ProjectNode( context.getIdAllocator().getNextId(), new AggregationNode( context.getIdAllocator().getNextId(), parent.getSubquery(), ImmutableMap.of(count, new Aggregation(COUNT_CALL, countSignature, Optional.empty())), globalAggregation(), ImmutableList.of(), AggregationNode.Step.SINGLE, Optional.empty(), Optional.empty()), Assignments.of(exists, new ComparisonExpression(GREATER_THAN, count.toSymbolReference(), new Cast(new LongLiteral("0"), BIGINT.toString())))), parent.getCorrelation(), INNER, parent.getOriginSubquery()); } }
private PlanNode rewriteToDefaultAggregation(ApplyNode parent, Context context) { Symbol count = context.getSymbolAllocator().newSymbol(COUNT.toString(), BIGINT); Symbol exists = getOnlyElement(parent.getSubqueryAssignments().getSymbols()); return new LateralJoinNode( parent.getId(), parent.getInput(), new ProjectNode( context.getIdAllocator().getNextId(), new AggregationNode( context.getIdAllocator().getNextId(), parent.getSubquery(), ImmutableMap.of(count, new Aggregation(COUNT_CALL, countSignature, Optional.empty())), globalAggregation(), ImmutableList.of(), AggregationNode.Step.SINGLE, Optional.empty(), Optional.empty()), Assignments.of(exists, new ComparisonExpression(GREATER_THAN, count.toSymbolReference(), new Cast(new LongLiteral("0"), BIGINT.toString())))), parent.getCorrelation(), INNER, parent.getOriginSubquery()); } }
@Override public Result apply(ApplyNode applyNode, Captures captures, Context context) { Assignments subqueryAssignments = applyNode.getSubqueryAssignments().rewrite(x -> rewriter.rewrite(x, context)); if (applyNode.getSubqueryAssignments().equals(subqueryAssignments)) { return Result.empty(); } return Result.ofPlanNode(new ApplyNode( applyNode.getId(), applyNode.getInput(), applyNode.getSubquery(), subqueryAssignments, applyNode.getCorrelation(), applyNode.getOriginSubquery())); } }
private Optional<PlanNode> rewriteToNonDefaultAggregation(ApplyNode applyNode, Context context) { checkState(applyNode.getSubquery().getOutputSymbols().isEmpty(), "Expected subquery output symbols to be pruned"); Symbol exists = getOnlyElement(applyNode.getSubqueryAssignments().getSymbols()); Symbol subqueryTrue = context.getSymbolAllocator().newSymbol("subqueryTrue", BOOLEAN); Assignments.Builder assignments = Assignments.builder(); assignments.putIdentities(applyNode.getInput().getOutputSymbols()); assignments.put(exists, new CoalesceExpression(ImmutableList.of(subqueryTrue.toSymbolReference(), BooleanLiteral.FALSE_LITERAL))); PlanNode subquery = new ProjectNode( context.getIdAllocator().getNextId(), new LimitNode( context.getIdAllocator().getNextId(), applyNode.getSubquery(), 1L, false), Assignments.of(subqueryTrue, TRUE_LITERAL)); PlanNodeDecorrelator decorrelator = new PlanNodeDecorrelator(context.getIdAllocator(), context.getLookup()); if (!decorrelator.decorrelateFilters(subquery, applyNode.getCorrelation()).isPresent()) { return Optional.empty(); } return Optional.of(new ProjectNode(context.getIdAllocator().getNextId(), new LateralJoinNode( applyNode.getId(), applyNode.getInput(), subquery, applyNode.getCorrelation(), LEFT, applyNode.getOriginSubquery()), assignments.build())); }
@Override public Result apply(ApplyNode applyNode, Captures captures, Context context) { Assignments subqueryAssignments = applyNode.getSubqueryAssignments().rewrite(x -> rewriter.rewrite(x, context)); if (applyNode.getSubqueryAssignments().equals(subqueryAssignments)) { return Result.empty(); } return Result.ofPlanNode(new ApplyNode( applyNode.getId(), applyNode.getInput(), applyNode.getSubquery(), subqueryAssignments, applyNode.getCorrelation(), applyNode.getOriginSubquery())); } }