@Override public ActualProperties visitExchange( ExchangeNode node, List<ActualProperties> inputProperties) { checkArgument( node.getScope() != REMOTE || inputProperties.stream().noneMatch(ActualProperties::isNullsReplicated), "Null replicated inputs should not be remotely exchanged"); Set<Map.Entry<Symbol, NullableValue>> entries = null; for (int sourceIndex = 0; sourceIndex < node.getSources().size(); sourceIndex++) { Map<Symbol, Symbol> inputToOutput = exchangeInputToOutput(node, sourceIndex); ActualProperties translated = inputProperties .get(sourceIndex) .translate(symbol -> Optional.ofNullable(inputToOutput.get(symbol))); entries = (entries == null) ? translated.getConstants().entrySet() : Sets.intersection(entries, translated.getConstants().entrySet()); } checkState(entries != null); Map<Symbol, NullableValue> constants = entries.stream().collect(toMap(Map.Entry::getKey, Map.Entry::getValue)); // Local exchanges are only created in AddLocalExchanges, at the end of optimization, and // local exchanges do not produce global properties as represented by ActualProperties. // This is acceptable because AddLocalExchanges does not use global properties and is only // interested in the local properties. // TODO: implement full properties for local exchanges if (node.getScope() == LOCAL) { return ActualProperties.builder().constants(constants).build(); } switch (node.getType()) { case GATHER: boolean coordinatorOnly = node.getPartitioningScheme().getPartitioning().getHandle().isCoordinatorOnly(); return ActualProperties.builder() .global( coordinatorOnly ? coordinatorSingleStreamPartition() : singleStreamPartition()) .constants(constants) .build(); case REPARTITION: return ActualProperties.builder() .global( partitionedOn( node.getPartitioningScheme().getPartitioning(), Optional.of(node.getPartitioningScheme().getPartitioning())) .withReplicatedNulls(node.getPartitioningScheme().isReplicateNulls())) .constants(constants) .build(); case REPLICATE: // TODO: this should have the same global properties as the stream taking the replicated // data return ActualProperties.builder() .global(arbitraryPartition()) .constants(constants) .build(); } throw new UnsupportedOperationException("not yet implemented"); }