return Result.empty(); return Result.ofPlanNode( new AggregationNode( parent.getId(),
private boolean exploreNode(int group, Context context, Matcher matcher) { PlanNode node = context.memo.getNode(group); boolean done = false; boolean progress = false; while (!done) { context.checkTimeoutNotExhausted(); done = true; Iterator<Rule<?>> possiblyMatchingRules = ruleIndex.getCandidates(node).iterator(); while (possiblyMatchingRules.hasNext()) { Rule<?> rule = possiblyMatchingRules.next(); if (!rule.isEnabled(context.session)) { continue; } Rule.Result result = transform(node, rule, matcher, context); if (result.getTransformedPlan().isPresent()) { node = context.memo.replace(group, result.getTransformedPlan().get(), rule.getClass().getName()); done = false; progress = true; } } } return progress; }
public static Result empty() { return new Result(Optional.empty()); }
return Result.ofPlanNode(restrictOutputs(context.getIdAllocator(), result, ImmutableSet.copyOf(project.getOutputSymbols())).orElse(result));
|| !groupsOnAllColumns(aggregation, getOuterTable(join).getOutputSymbols()) || !isDistinct(context.getLookup().resolve(getOuterTable(join)), context.getLookup()::resolve)) { return Result.empty(); return Result.empty(); return Result.ofPlanNode(resultNode.get());
.recurseOnlyWhen(ProjectNode.class::isInstance) .matches()) { return Result.empty(); return Result.ofPlanNode(new LateralJoinNode( context.getIdAllocator().getNextId(), lateralJoinNode.getInput(), BOOLEAN)))); return Result.ofPlanNode(new ProjectNode( context.getIdAllocator().getNextId(), filterNode,
decomposable, "Distributed aggregation with empty grouping set requires partial but functions are not decomposable"); return Result.ofPlanNode(split(aggregationNode, context)); return Result.empty(); return Result.empty(); return Result.empty(); return Result.empty(); case SINGLE: return Result.ofPlanNode(split(aggregationNode, context)); case PARTIAL: return Result.ofPlanNode(pushPartial(aggregationNode, exchangeNode, context)); default: return Result.empty();
return Result.ofPlanNode( new AggregationNode( context.getIdAllocator().getNextId(),
@VisibleForTesting public static final class ExtractSpatialLeftJoin implements Rule<JoinNode> { private static final Pattern<JoinNode> PATTERN = join().matching(node -> node.getCriteria().isEmpty() && node.getFilter().isPresent() && node.getType() == LEFT); private final Metadata metadata; private final SplitManager splitManager; private final PageSourceManager pageSourceManager; private final SqlParser sqlParser; public ExtractSpatialLeftJoin(Metadata metadata, SplitManager splitManager, PageSourceManager pageSourceManager, SqlParser sqlParser) { this.metadata = requireNonNull(metadata, "metadata is null"); this.splitManager = requireNonNull(splitManager, "splitManager is null"); this.pageSourceManager = requireNonNull(pageSourceManager, "pageSourceManager is null"); this.sqlParser = requireNonNull(sqlParser, "sqlParser is null"); } @Override public boolean isEnabled(Session session) { return isSpatialJoinEnabled(session); } @Override public Pattern<JoinNode> getPattern() { return PATTERN; }
return Result.ofPlanNode( new AggregationNode( node.getId(),
return Result.empty(); return Result.ofPlanNode( new ProjectNode( parent.getId(),
return Result.empty(); return Result.empty(); return Result.ofPlanNode(new AggregationNode( node.getId(), node.getSource(),
.collect(Collectors.toSet()); return Result.ofPlanNode( new AggregationNode( aggregation.getId(),
@Override public Result apply(AggregationNode parent, Captures captures, Context context) { ProjectNode child = captures.get(CHILD); boolean changed = false; Map<Symbol, AggregationNode.Aggregation> aggregations = new LinkedHashMap<>(parent.getAggregations()); for (Entry<Symbol, AggregationNode.Aggregation> entry : parent.getAggregations().entrySet()) { Symbol symbol = entry.getKey(); AggregationNode.Aggregation aggregation = entry.getValue(); if (isCountOverConstant(aggregation, child.getAssignments())) { changed = true; aggregations.put(symbol, new AggregationNode.Aggregation( new FunctionCall(QualifiedName.of("count"), ImmutableList.of()), new Signature("count", AGGREGATE, parseTypeSignature(StandardTypes.BIGINT)), aggregation.getMask())); } } if (!changed) { return Result.empty(); } return Result.ofPlanNode(new AggregationNode( parent.getId(), child, aggregations, parent.getGroupingSets(), ImmutableList.of(), parent.getStep(), parent.getHashSymbol(), parent.getGroupIdSymbol())); }
.orElse(Result.empty());
@Override public Result apply(AggregationNode aggregation, Captures captures, Context context) { Lookup lookup = context.getLookup(); PlanNodeIdAllocator idAllocator = context.getIdAllocator(); Session session = context.getSession(); Optional<PlanNode> rewrittenSource = recurseToPartial(lookup.resolve(aggregation.getSource()), lookup, idAllocator); if (!rewrittenSource.isPresent()) { return Result.empty(); } PlanNode source = rewrittenSource.get(); if (getTaskConcurrency(session) > 1) { source = ExchangeNode.partitionedExchange( idAllocator.getNextId(), ExchangeNode.Scope.LOCAL, source, new PartitioningScheme(Partitioning.create(FIXED_ARBITRARY_DISTRIBUTION, ImmutableList.of()), source.getOutputSymbols())); source = new AggregationNode( idAllocator.getNextId(), source, inputsAsOutputs(aggregation.getAggregations()), aggregation.getGroupingSets(), aggregation.getPreGroupedSymbols(), AggregationNode.Step.INTERMEDIATE, aggregation.getHashSymbol(), aggregation.getGroupIdSymbol()); source = ExchangeNode.gatheringExchange(idAllocator.getNextId(), ExchangeNode.Scope.LOCAL, source); } return Result.ofPlanNode(aggregation.replaceChildren(ImmutableList.of(source))); }
return Result.ofPlanNode(new UnionNode(parent.getId(), outputSources.build(), mappings.build(), ImmutableList.copyOf(mappings.build().keySet())));
@Override public Result apply(AggregationNode aggregationNode, Captures captures, Context context) { boolean anyRewritten = false; ImmutableMap.Builder<Symbol, Aggregation> aggregations = ImmutableMap.builder(); for (Map.Entry<Symbol, Aggregation> entry : aggregationNode.getAggregations().entrySet()) { Aggregation aggregation = entry.getValue(); FunctionCall call = (FunctionCall) rewriter.rewrite(aggregation.getCall(), context); aggregations.put( entry.getKey(), new Aggregation(call, aggregation.getSignature(), aggregation.getMask())); if (!aggregation.getCall().equals(call)) { anyRewritten = true; } } if (anyRewritten) { return Result.ofPlanNode(new AggregationNode( aggregationNode.getId(), aggregationNode.getSource(), aggregations.build(), aggregationNode.getGroupingSets(), aggregationNode.getPreGroupedSymbols(), aggregationNode.getStep(), aggregationNode.getHashSymbol(), aggregationNode.getGroupIdSymbol())); } return Result.empty(); } }
@Override public Result apply(ExchangeNode node, Captures captures, Context context) { checkArgument(!node.getOrderingScheme().isPresent(), "Merge exchange over AssignUniqueId not supported"); AssignUniqueId assignUniqueId = captures.get(ASSIGN_UNIQUE_ID); PartitioningScheme partitioningScheme = node.getPartitioningScheme(); if (partitioningScheme.getPartitioning().getColumns().contains(assignUniqueId.getIdColumn())) { // The column produced by the AssignUniqueId is used in the partitioning scheme of the exchange. // Hence, AssignUniqueId node has to stay below the exchange node. return Result.empty(); } return Result.ofPlanNode(new AssignUniqueId( assignUniqueId.getId(), new ExchangeNode( node.getId(), node.getType(), node.getScope(), new PartitioningScheme( partitioningScheme.getPartitioning(), removeSymbol(partitioningScheme.getOutputLayout(), assignUniqueId.getIdColumn()), partitioningScheme.getHashColumn(), partitioningScheme.isReplicateNullsAndAny(), partitioningScheme.getBucketToPartition()), ImmutableList.of(assignUniqueId.getSource()), ImmutableList.of(removeSymbol(getOnlyElement(node.getInputs()), assignUniqueId.getIdColumn())), Optional.empty()), assignUniqueId.getIdColumn())); }
@Override public Result apply(ApplyNode applyNode, Captures captures, Context context) { if (applyNode.getSubqueryAssignments().size() != 1) { return Result.empty(); } Expression expression = getOnlyElement(applyNode.getSubqueryAssignments().getExpressions()); if (!(expression instanceof InPredicate)) { return Result.empty(); } InPredicate inPredicate = (InPredicate) expression; Symbol semiJoinSymbol = getOnlyElement(applyNode.getSubqueryAssignments().getSymbols()); SemiJoinNode replacement = new SemiJoinNode(context.getIdAllocator().getNextId(), applyNode.getInput(), applyNode.getSubquery(), Symbol.from(inPredicate.getValue()), Symbol.from(inPredicate.getValueList()), semiJoinSymbol, Optional.empty(), Optional.empty(), Optional.empty()); return Result.ofPlanNode(replacement); } }