presto-main/src/main/java/io/prestosql/sql/planner/iterative/rule/PruneJoinChildrenColumns.java/PruneJoinChildrenColumns/apply
class PruneJoinChildrenColumns:    @Override
    public Result apply(JoinNode joinNode, Captures captures, Context context)
    {
        Set<Symbol> globallyUsableInputs = ImmutableSet.<Symbol>builder()
                .addAll(joinNode.getOutputSymbols())
                .addAll(
                        joinNode.getFilter()
                                .map(SymbolsExtractor::extractUnique)
                                .orElse(ImmutableSet.of()))
                .build();

        Set<Symbol> leftUsableInputs = ImmutableSet.<Symbol>builder()
                .addAll(globallyUsableInputs)
                .addAll(
                        joinNode.getCriteria().stream()
                                .map(JoinNode.EquiJoinClause::getLeft)
                                .iterator())
                .addAll(joinNode.getLeftHashSymbol().map(ImmutableSet::of).orElse(ImmutableSet.of()))
                .build();

        Set<Symbol> rightUsableInputs = ImmutableSet.<Symbol>builder()
                .addAll(globallyUsableInputs)
                .addAll(
                        joinNode.getCriteria().stream()
                                .map(JoinNode.EquiJoinClause::getRight)
                                .iterator())
                .addAll(joinNode.getRightHashSymbol().map(ImmutableSet::of).orElse(ImmutableSet.of()))
                .build();

        return restrictChildOutputs(context.getIdAllocator(), joinNode, leftUsableInputs, rightUsableInputs)
                .map(Result::ofPlanNode)
                .orElse(Result.empty());
    }