Source:
<code>public ActualProperties visitJoin(JoinNode node, List<ActualProperties> inputProperties) { ActualProperties probeProperties = inputProperties.get(0); ActualProperties buildProperties = inputProperties.get(1); boolean unordered = spillPossible(session, node.getType()); switch (node.getType()) { case INNER: probeProperties = probeProperties.translate(column -> filterOrRewrite(node.getOutputSymbols(), node.getCriteria(), column)); buildProperties = buildProperties.translate(column -> filterOrRewrite(node.getOutputSymbols(), node.getCriteria(), column)); Map<Symbol, NullableValue> constants = new HashMap<>(); constants.putAll(probeProperties.getConstants()); constants.putAll(buildProperties.getConstants()); List<LocalProperty<Symbol>> newLocalProbeProperties; if (node.isCrossJoin()) { Set<Symbol> probeConstants = LocalProperties.extractLeadingConstants(probeProperties.getLocalProperties()); newLocalProbeProperties = probeConstants.stream().map(ConstantProperty::new).collect(toImmutableList()); } else { newLocalProbeProperties = probeProperties.getLocalProperties(); } return ActualProperties.builderFrom(probeProperties) <START> .local(newLocalProbeProperties) <END> .constants(constants) .unordered(unordered) .build(); case LEFT: return ActualProperties.builderFrom(probeProperties.translate(column -> filterIfMissing(node.getOutputSymbols(), column))) .unordered(unordered) .build(); case RIGHT: buildProperties = buildProperties.translate(column -> filterIfMissing(node.getOutputSymbols(), column)); return ActualProperties.builderFrom(buildProperties.translate(column -> filterIfMissing(node.getOutputSymbols(), column))) .local(ImmutableList.of()) .unordered(unordered) .build(); case FULL: return ActualProperties.builder() .global(probeProperties.isSingleNode() ? singleStreamPartition() : arbitraryPartition()) .unordered(unordered) .build(); default: throw new UnsupportedOperationException("Unsupported join type: " + node.getType()); } }</code><technical_language>this implicitly strips grouping other properties too, yes</technical_language>

Target:
public ActualProperties visitJoin(JoinNode node, List<ActualProperties> inputProperties) { ActualProperties probeProperties = inputProperties.get(0); ActualProperties buildProperties = inputProperties.get(1); boolean unordered = spillPossible(session, node.getType()); switch (node.getType()) { case INNER: probeProperties = probeProperties.translate(column -> filterOrRewrite(node.getOutputSymbols(), node.getCriteria(), column)); buildProperties = buildProperties.translate(column -> filterOrRewrite(node.getOutputSymbols(), node.getCriteria(), column)); Map<Symbol, NullableValue> constants = new HashMap<>(); constants.putAll(probeProperties.getConstants()); constants.putAll(buildProperties.getConstants()); if (node.isCrossJoin()) { return ActualProperties.builder() .global(probeProperties) .local(ImmutableList.of()) .constants(constants) .build(); } return ActualProperties.builderFrom(probeProperties) .constants(constants) .unordered(unordered) .build(); case LEFT: return ActualProperties.builderFrom(probeProperties.translate(column -> filterIfMissing(node.getOutputSymbols(), column))) .unordered(unordered) .build(); case RIGHT: buildProperties = buildProperties.translate(column -> filterIfMissing(node.getOutputSymbols(), column)); return ActualProperties.builderFrom(buildProperties.translate(column -> filterIfMissing(node.getOutputSymbols(), column))) .local(ImmutableList.of()) .unordered(unordered) .build(); case FULL: return ActualProperties.builder() .global(probeProperties.isSingleNode() ? singleStreamPartition() : arbitraryPartition()) .unordered(unordered) .build(); default: throw new UnsupportedOperationException("Unsupported join type: " + node.getType()); } }