if (left.getProperties().isSingleNode()) { if (!right.getProperties().isSingleNode()) { right = withDerivedProperties( gatheringExchange(idAllocator.getNextId(), REMOTE, right.getNode()), right.getProperties()); right = withDerivedProperties( replicatedExchange(idAllocator.getNextId(), REMOTE, right.getNode()), right.getProperties()); left = withDerivedProperties( partitionedExchange(idAllocator.getNextId(), REMOTE, left.getNode(), ImmutableList.of(node.getLeftPartitionSymbol().get()), Optional.empty()), left.getProperties()); right = withDerivedProperties( partitionedExchange(idAllocator.getNextId(), REMOTE, right.getNode(), ImmutableList.of(node.getRightPartitionSymbol().get()), Optional.empty()), right.getProperties()); return new PlanWithProperties(newJoinNode, deriveProperties(newJoinNode, ImmutableList.of(left.getProperties(), right.getProperties())));
private PlanWithProperties planTableScan(TableScanNode node, Expression predicate, PreferredProperties preferredProperties) { List<PlanNode> possiblePlans = PickTableLayout.listTableLayouts(node, predicate, true, session, types, idAllocator, metadata, parser, domainTranslator); List<PlanWithProperties> possiblePlansWithProperties = possiblePlans.stream() .map(planNode -> new PlanWithProperties(planNode, derivePropertiesRecursively(planNode))) .collect(toImmutableList()); return pickPlan(possiblePlansWithProperties, preferredProperties); }
@Override public PlanWithProperties visitSort(SortNode node, PreferredProperties preferredProperties) PlanWithProperties child = planChild(node, PreferredProperties.undistributed()); child = planChild(node, PreferredProperties.any()); return withDerivedProperties( mergingExchange( idAllocator.getNextId(), child = withDerivedProperties( gatheringExchange(idAllocator.getNextId(), REMOTE, child.getNode()), child.getProperties()); return rebaseAndDeriveProperties(node, child);
source = withDerivedProperties( partitionedExchange( idAllocator.getNextId(),
left = withDerivedProperties( partitionedExchange(idAllocator.getNextId(), left.getNode(), leftSymbols, node.getLeftHashSymbol()), left.getProperties()); right = withDerivedProperties( gatheringExchange(idAllocator.getNextId(), right.getNode()), right.getProperties()); Optional.empty()); right = withDerivedProperties( partitionedExchange(idAllocator.getNextId(), right.getNode(), partitionFunction), right.getProperties()); right = withDerivedProperties( gatheringExchange(idAllocator.getNextId(), right.getNode()), right.getProperties()); right = withDerivedProperties( replicatedExchange(idAllocator.getNextId(), right.getNode()), right.getProperties()); node.getRightHashSymbol()); return new PlanWithProperties(result, deriveProperties(result, ImmutableList.of(left.getProperties(), right.getProperties())));
source = withDerivedProperties( partitionedExchange(idAllocator.getNextId(), source.getNode(), sourceSymbols, node.getSourceHashSymbol()), source.getProperties()); true, Optional.empty()); filteringSource = withDerivedProperties( partitionedExchange( idAllocator.getNextId(), filteringSource = withDerivedProperties( gatheringExchange(idAllocator.getNextId(), filteringSource.getNode()), filteringSource.getProperties()); filteringSource = withDerivedProperties( replicatedExchange(idAllocator.getNextId(), filteringSource.getNode()), filteringSource.getProperties()); return rebaseAndDeriveProperties(node, ImmutableList.of(source, filteringSource));
new Constraint<>(simplifiedConstraint, bindings -> !shouldPrune(constraint, node.getAssignments(), bindings)), Optional.of(node.getOutputSymbols().stream() .map(node.getAssignments()::get) .filter(layoutHasAllNeededOutputs(node)) .collect(toList()); checkState(!layouts.isEmpty(), "No usable layouts for %s", node); Optional.ofNullable(node.getOriginalConstraint()).orElse(predicate)); PlanWithProperties result = new PlanWithProperties(tableScan, deriveProperties(tableScan, ImmutableList.of())); return withDerivedProperties( new FilterNode(idAllocator.getNextId(), result.getNode(), resultingPredicate), deriveProperties(tableScan, ImmutableList.of())); .collect(toList()); return pickPlan(possiblePlans, context);
PlanWithProperties child = planChild( node, context.withPreferredProperties(PreferredProperties.derivePreferences(context.getPreferredProperties(), ImmutableSet.copyOf(node.getPartitionBy()), desiredProperties))); child = withDerivedProperties( gatheringExchange(idAllocator.getNextId(), child.getNode()), child.getProperties()); child = withDerivedProperties( partitionedExchange(idAllocator.getNextId(), child.getNode(), node.getPartitionBy(), node.getHashSymbol()), child.getProperties()); return withDerivedProperties( new WindowNode( node.getId(),
PlanWithProperties partial = withDerivedProperties( new AggregationNode( idAllocator.getNextId(), return withDerivedProperties( new AggregationNode( node.getId(), node.getConfidence(), node.getHashSymbol()), deriveProperties(source, partial.getProperties()));
: PreferredProperties.derivePreferences(context.getPreferredProperties(), ImmutableSet.copyOf(node.getGroupBy()), Optional.of(node.getGroupBy()), grouped(node.getGroupBy())); PlanWithProperties child = planChild(node, context.withPreferredProperties(preferredProperties)); return rebaseAndDeriveProperties(node, child); return splitAggregation(node, child, partial -> gatheringExchange(idAllocator.getNextId(), partial)); child = withDerivedProperties( gatheringExchange(idAllocator.getNextId(), child.getNode()), child.getProperties()); return rebaseAndDeriveProperties(node, child); return rebaseAndDeriveProperties(node, child); node.getHashSymbol()); return splitAggregation(node, child, exchanger); child = withDerivedProperties( partitionedExchange(idAllocator.getNextId(), child.getNode(), node.getGroupBy(), node.getHashSymbol()), child.getProperties()); return rebaseAndDeriveProperties(node, child);
PlanWithProperties child = planChild(node, context.withPreferredProperties(preferredChildProperties)); if (!child.getProperties().isStreamPartitionedOn(node.getPartitionBy())) { child = withDerivedProperties( new TopNRowNumberNode( idAllocator.getNextId(), child.getProperties()); child = withDerivedProperties(addExchange.apply(child.getNode()), child.getProperties()); return rebaseAndDeriveProperties(node, child);
@Override public PlanWithProperties visitRowNumber(RowNumberNode node, Context context) { if (node.getPartitionBy().isEmpty()) { PlanWithProperties child = planChild(node, context.withPreferredProperties(PreferredProperties.undistributed())); if (!child.getProperties().isSingleNode()) { child = withDerivedProperties( gatheringExchange(idAllocator.getNextId(), child.getNode()), child.getProperties()); } return rebaseAndDeriveProperties(node, child); } PlanWithProperties child = planChild(node, context.withPreferredProperties(PreferredProperties.derivePreferences(context.getPreferredProperties(), ImmutableSet.copyOf(node.getPartitionBy()), grouped(node.getPartitionBy())))); // TODO: add config option/session property to force parallel plan if child is unpartitioned and window has a PARTITION BY clause if (!child.getProperties().isStreamPartitionedOn(node.getPartitionBy())) { child = withDerivedProperties( partitionedExchange( idAllocator.getNextId(), child.getNode(), node.getPartitionBy(), node.getHashSymbol()), child.getProperties()); } // TODO: streaming return rebaseAndDeriveProperties(node, child); }
@Override public PlanWithProperties visitIndexJoin(IndexJoinNode node, Context context) { List<Symbol> joinColumns = Lists.transform(node.getCriteria(), IndexJoinNode.EquiJoinClause::getProbe); // Only prefer grouping on join columns if no parent local property preferences List<LocalProperty<Symbol>> desiredLocalProperties = context.getPreferredProperties().getLocalProperties().isEmpty() ? grouped(joinColumns) : ImmutableList.of(); PlanWithProperties probeSource = node.getProbeSource().accept(this, context.withPreferredProperties(PreferredProperties.derivePreferences(context.getPreferredProperties(), ImmutableSet.copyOf(joinColumns), desiredLocalProperties))); ActualProperties probeProperties = probeSource.getProperties(); PlanWithProperties indexSource = node.getIndexSource().accept(this, context.withPreferredProperties(PreferredProperties.any())); // TODO: allow repartitioning if unpartitioned to increase parallelism if (shouldRepartitionForIndexJoin(joinColumns, context.getPreferredProperties(), probeProperties)) { probeSource = withDerivedProperties( partitionedExchange(idAllocator.getNextId(), probeSource.getNode(), joinColumns, node.getProbeHashSymbol()), probeProperties); } // TODO: if input is grouped, create streaming join // index side is really a nested-loops plan, so don't add exchanges PlanNode result = ChildReplacer.replaceChildren(node, ImmutableList.of(probeSource.getNode(), node.getIndexSource())); return new PlanWithProperties(result, deriveProperties(result, ImmutableList.of(probeSource.getProperties(), indexSource.getProperties()))); }
@Override public PlanWithProperties visitTableWriter(TableWriterNode node, Context context) { PlanWithProperties source = node.getSource().accept(this, context); Optional<PartitionFunctionBinding> partitionFunction = node.getPartitionFunction(); if (!partitionFunction.isPresent() && redistributeWrites) { partitionFunction = Optional.of(new PartitionFunctionBinding(FIXED_RANDOM_DISTRIBUTION, source.getNode().getOutputSymbols(), ImmutableList.of())); } if (partitionFunction.isPresent()) { source = withDerivedProperties( partitionedExchange( idAllocator.getNextId(), source.getNode(), partitionFunction.get()), source.getProperties() ); } return rebaseAndDeriveProperties(node, source); }
@Override public PlanWithProperties visitMarkDistinct(MarkDistinctNode node, Context context) { PreferredProperties preferredChildProperties = PreferredProperties.derivePreferences(context.getPreferredProperties(), ImmutableSet.copyOf(node.getDistinctSymbols()), Optional.of(node.getDistinctSymbols()), grouped(node.getDistinctSymbols())); PlanWithProperties child = node.getSource().accept(this, context.withPreferredProperties(preferredChildProperties)); if (child.getProperties().isSingleNode() || !child.getProperties().isStreamPartitionedOn(node.getDistinctSymbols())) { child = withDerivedProperties( partitionedExchange( idAllocator.getNextId(), child.getNode(), node.getDistinctSymbols(), node.getHashSymbol()), child.getProperties()); } return rebaseAndDeriveProperties(node, child); }
@Override public PlanWithProperties visitTableFinish(TableFinishNode node, Context context) { PlanWithProperties child = planChild(node, context.withPreferredProperties(PreferredProperties.any())); // if the child is already a gathering exchange, don't add another if ((child.getNode() instanceof ExchangeNode) && ((ExchangeNode) child.getNode()).getType().equals(ExchangeNode.Type.GATHER)) { return rebaseAndDeriveProperties(node, child); } if (!child.getProperties().isSingleNode() || !child.getProperties().isCoordinatorOnly()) { child = withDerivedProperties( gatheringExchange(idAllocator.getNextId(), child.getNode()), child.getProperties()); } return rebaseAndDeriveProperties(node, child); }
@Override public PlanWithProperties visitLimit(LimitNode node, Context context) { PlanWithProperties child = planChild(node, context.withPreferredProperties(PreferredProperties.any())); if (!child.getProperties().isSingleNode()) { child = withDerivedProperties( new LimitNode(idAllocator.getNextId(), child.getNode(), node.getCount()), child.getProperties()); child = withDerivedProperties( gatheringExchange(idAllocator.getNextId(), child.getNode()), child.getProperties()); } return rebaseAndDeriveProperties(node, child); }
@Override public PlanWithProperties visitTopN(TopNNode node, Context context) { PlanWithProperties child = planChild(node, context.withPreferredProperties(PreferredProperties.any())); if (!child.getProperties().isSingleNode()) { child = withDerivedProperties( new TopNNode(idAllocator.getNextId(), child.getNode(), node.getCount(), node.getOrderBy(), node.getOrderings(), true), child.getProperties()); child = withDerivedProperties( gatheringExchange(idAllocator.getNextId(), child.getNode()), child.getProperties()); } return rebaseAndDeriveProperties(node, child); }
private PlanWithProperties withDerivedProperties(PlanNode node, ActualProperties inputProperties) { return new PlanWithProperties(node, deriveProperties(node, inputProperties)); }
@Override public PlanWithProperties visitDistinctLimit(DistinctLimitNode node, Context context) { PlanWithProperties child = planChild(node, context.withPreferredProperties(PreferredProperties.any())); if (!child.getProperties().isSingleNode()) { child = withDerivedProperties( gatheringExchange( idAllocator.getNextId(), new DistinctLimitNode(idAllocator.getNextId(), child.getNode(), node.getLimit(), node.getHashSymbol())), child.getProperties()); } return rebaseAndDeriveProperties(node, child); }