presto-main/src/main/java/io/prestosql/sql/planner/plan/SetOperationNode.java/SetOperationNode/SetOperationNode
class SetOperationNode:    @JsonCreator
    protected SetOperationNode(
            @JsonProperty("id") PlanNodeId id,
            @JsonProperty("sources") List<PlanNode> sources,
            @JsonProperty("outputToInputs") ListMultimap<Symbol, Symbol> outputToInputs,
            @JsonProperty("outputs") List<Symbol> outputs)
    {
        super(id);

        requireNonNull(sources, "sources is null");
        checkArgument(!sources.isEmpty(), "Must have at least one source");
        requireNonNull(outputToInputs, "outputToInputs is null");
        requireNonNull(outputs, "outputs is null");

        this.sources = ImmutableList.copyOf(sources);
        this.outputToInputs = ImmutableListMultimap.copyOf(outputToInputs);
        this.outputs = ImmutableList.copyOf(outputs);

        for (Collection<Symbol> inputs : this.outputToInputs.asMap().values()) {
            checkArgument(inputs.size() == this.sources.size(), "Every source needs to map its symbols to an output %s operation symbol", this.getClass().getSimpleName());
        }

        // Make sure each source positionally corresponds to their Symbol values in the Multimap
        for (int i = 0; i < sources.size(); i++) {
            for (Collection<Symbol> expectedInputs : this.outputToInputs.asMap().values()) {
                checkArgument(sources.get(i).getOutputSymbols().contains(Iterables.get(expectedInputs, i)), "Source does not provide required symbols");
            }
        }
    }