Type type = context.getSymbolAllocator().getTypes().get(projection.getKey()); Symbol symbol = context.getSymbolAllocator().newSymbol(translatedExpression, type); projections.put(symbol, translatedExpression); inputs.add(symbol); newSourceBuilder.add(new ProjectNode(context.getIdAllocator().getNextId(), exchange.getSources().get(i), projections.build())); inputsBuilder.add(inputs.build()); return Result.ofPlanNode(restrictOutputs(context.getIdAllocator(), result, ImmutableSet.copyOf(project.getOutputSymbols())).orElse(result));
@Override public Result apply(AggregationNode parent, Captures captures, Context context) { if (!parent.hasDefaultOutput() || parent.getOutputSymbols().size() != 1) { return Result.empty(); } Map<Symbol, AggregationNode.Aggregation> assignments = parent.getAggregations(); for (Map.Entry<Symbol, AggregationNode.Aggregation> entry : assignments.entrySet()) { AggregationNode.Aggregation aggregation = entry.getValue(); requireNonNull(aggregation, "aggregation is null"); Signature signature = aggregation.getSignature(); FunctionCall functionCall = aggregation.getCall(); if (!"count".equals(signature.getName()) || !functionCall.getArguments().isEmpty()) { return Result.empty(); } } if (!assignments.isEmpty() && isScalar(parent.getSource(), context.getLookup())) { return Result.ofPlanNode(new ValuesNode(parent.getId(), parent.getOutputSymbols(), ImmutableList.of(ImmutableList.of(new LongLiteral("1"))))); } return Result.empty(); } }
@Override public Result apply(AggregationNode parent, Captures captures, Context context) if (!SystemSessionProperties.useMarkDistinct(context.getSession())) { return Result.empty(); marker = context.getSymbolAllocator().newSymbol(Iterables.getLast(inputs).getName(), BOOLEAN, "distinct"); markers.put(inputs, marker); context.getIdAllocator().getNextId(), subPlan, marker,
|| !(join.getType() == JoinNode.Type.LEFT || join.getType() == JoinNode.Type.RIGHT) || !groupsOnAllColumns(aggregation, getOuterTable(join).getOutputSymbols()) || !isDistinct(context.getLookup().resolve(getOuterTable(join)), context.getLookup()::resolve)) { return Result.empty(); Optional<PlanNode> resultNode = coalesceWithNullAggregation(rewrittenAggregation, rewrittenJoin, context.getSymbolAllocator(), context.getIdAllocator(), context.getLookup()); if (!resultNode.isPresent()) { return Result.empty();
PlanNode subquery = context.getLookup().resolve(lateralJoinNode.getSubquery()); if (!searchFrom(subquery, context.getLookup()) .where(EnforceSingleRowNode.class::isInstance) .recurseOnlyWhen(ProjectNode.class::isInstance) PlanNode rewrittenSubquery = searchFrom(subquery, context.getLookup()) .where(EnforceSingleRowNode.class::isInstance) .recurseOnlyWhen(ProjectNode.class::isInstance) .removeFirst(); if (isAtMostScalar(rewrittenSubquery, context.getLookup())) { return Result.ofPlanNode(new LateralJoinNode( context.getIdAllocator().getNextId(), lateralJoinNode.getInput(), rewrittenSubquery, Symbol unique = context.getSymbolAllocator().newSymbol("unique", BigintType.BIGINT); context.getIdAllocator().getNextId(), new AssignUniqueId( context.getIdAllocator().getNextId(), lateralJoinNode.getInput(), unique), Symbol isDistinct = context.getSymbolAllocator().newSymbol("is_distinct", BooleanType.BOOLEAN); MarkDistinctNode markDistinctNode = new MarkDistinctNode( context.getIdAllocator().getNextId(), rewrittenLateralJoinNode,
if (!decomposable || !preferPartialAggregation(context.getSession())) { return Result.empty();
Symbol symbol = context.getSymbolAllocator().newSymbol(filter, BOOLEAN); verify(!mask.isPresent(), "Expected aggregation without mask symbols, see Rule pattern"); newAssignments.put(symbol, filter); context.getIdAllocator().getNextId(), new FilterNode( context.getIdAllocator().getNextId(), new ProjectNode( context.getIdAllocator().getNextId(), aggregation.getSource(), newAssignments.build()),
Signature signature = originalAggregation.getSignature(); InternalAggregationFunction function = functionRegistry.getAggregateFunctionImplementation(signature); Symbol intermediateSymbol = context.getSymbolAllocator().newSymbol(signature.getName(), function.getIntermediateType()); context.getIdAllocator().getNextId(), node.getSource(), intermediateAggregation,
@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; }
Symbol partitionCountSymbol = context.getSymbolAllocator().newSymbol("partition_count", INTEGER); ImmutableMap.Builder<Symbol, Expression> envelopeAssignments = ImmutableMap.builder(); for (Map.Entry<Symbol, Aggregation> entry : node.getAggregations().entrySet()) { if (name.toString().equals(NAME) && call.getArguments().size() == 1) { Expression geometry = getOnlyElement(call.getArguments()); Symbol envelopeSymbol = context.getSymbolAllocator().newSymbol("envelope", metadata.getType(GEOMETRY_TYPE_SIGNATURE)); if (geometry instanceof FunctionCall && ((FunctionCall) geometry).getName().toString().equalsIgnoreCase("ST_Envelope")) { envelopeAssignments.put(envelopeSymbol, geometry); node.getId(), new ProjectNode( context.getIdAllocator().getNextId(), node.getSource(), Assignments.builder() .putIdentities(node.getSource().getOutputSymbols()) .put(partitionCountSymbol, new LongLiteral(Integer.toString(getHashPartitionCount(context.getSession())))) .putAll(envelopeAssignments.build()) .build()),
AggregationNode mappedPartial = symbolMapper.map(aggregation, source, context.getIdAllocator()); assignments.put(output, input.toSymbolReference()); partials.add(new ProjectNode(context.getIdAllocator().getNextId(), mappedPartial, assignments.build())); context.getIdAllocator().getNextId(), exchange.getType(), exchange.getScope(),
aggregation.getId(), new AggregationNode( context.getIdAllocator().getNextId(), aggregation.getSource(), ImmutableMap.of(),
.build(); return restrictChildOutputs(context.getIdAllocator(), joinNode, leftUsableInputs, rightUsableInputs) .map(Result::ofPlanNode) .orElse(Result.empty());
private PlanNodeWithCost getSemiJoinNodeWithCost(SemiJoinNode possibleJoinNode, Context context) TypeProvider types = context.getSymbolAllocator().getTypes(); StatsProvider stats = context.getStatsProvider(); boolean replicated = possibleJoinNode.getDistributionType().get().equals(REPLICATED);
private PlanNodeWithCost getJoinNodeWithCost(Context context, JoinNode possibleJoinNode) TypeProvider types = context.getSymbolAllocator().getTypes(); StatsProvider stats = context.getStatsProvider(); boolean replicated = possibleJoinNode.getDistributionType().get().equals(REPLICATED);
@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))); }
Type type = context.getSymbolAllocator().getTypes().get(entry.getKey()); Symbol symbol = context.getSymbolAllocator().newSymbol(translatedExpression, type); assignments.put(symbol, translatedExpression); projectSymbolMapping.put(entry.getKey(), symbol); outputSources.add(new ProjectNode(context.getIdAllocator().getNextId(), source.getSources().get(i), assignments.build())); outputLayout.forEach(symbol -> mappings.put(symbol, projectSymbolMapping.get(symbol)));
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 JoinEnumerationResult chooseJoinOrder(LinkedHashSet<PlanNode> sources, List<Symbol> outputSymbols) { context.checkTimeoutNotExhausted(); Set<PlanNode> multiJoinKey = ImmutableSet.copyOf(sources); JoinEnumerationResult bestResult = memo.get(multiJoinKey); if (bestResult == null) { checkState(sources.size() > 1, "sources size is less than or equal to one"); ImmutableList.Builder<JoinEnumerationResult> resultBuilder = ImmutableList.builder(); Set<Set<Integer>> partitions = generatePartitions(sources.size()); for (Set<Integer> partition : partitions) { JoinEnumerationResult result = createJoinAccordingToPartitioning(sources, outputSymbols, partition); if (result.equals(UNKNOWN_COST_RESULT)) { memo.put(multiJoinKey, result); return result; } if (!result.equals(INFINITE_COST_RESULT)) { resultBuilder.add(result); } } List<JoinEnumerationResult> results = resultBuilder.build(); if (results.isEmpty()) { memo.put(multiJoinKey, INFINITE_COST_RESULT); return INFINITE_COST_RESULT; } bestResult = resultComparator.min(results); memo.put(multiJoinKey, bestResult); } bestResult.planNode.ifPresent((planNode) -> log.debug("Least cost join was: %s", planNode)); return bestResult; }
private static TableWriterNode rewriteSource( TableWriterNode writerNode, UnionNode unionNode, int source, List<Map<Symbol, Symbol>> sourceMappings, Context context) { Map<Symbol, Symbol> inputMappings = getInputSymbolMapping(unionNode, source); ImmutableMap.Builder<Symbol, Symbol> mappings = ImmutableMap.builder(); mappings.putAll(inputMappings); ImmutableMap.Builder<Symbol, Symbol> outputMappings = ImmutableMap.builder(); for (Symbol outputSymbol : writerNode.getOutputSymbols()) { if (inputMappings.containsKey(outputSymbol)) { outputMappings.put(outputSymbol, inputMappings.get(outputSymbol)); } else { Symbol newSymbol = context.getSymbolAllocator().newSymbol(outputSymbol); outputMappings.put(outputSymbol, newSymbol); mappings.put(outputSymbol, newSymbol); } } sourceMappings.add(outputMappings.build()); SymbolMapper symbolMapper = new SymbolMapper(mappings.build()); return symbolMapper.map(writerNode, unionNode.getSources().get(source), context.getIdAllocator().getNextId()); }