### Description

Evals that introduce aliased can be simplified by extracting them into a project (and thus signaling there's no underlying processing).

The following eval:
`eval x = a + 1, y = x, z = y + 1, y = z, w = y + 1`
can be converted into:
`eval x = a + 1, z = a + 1 + 1, w = a + 1 + 1 | project x, z, z as y, w`

This helps fuse the project with other projections/aggs downstream.
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/Layout.java
*/
    List<ChannelSet> inverse();
    /**
     * Builder class for Layout. The builder ensures that layouts cannot be altered after creation (through references to the underlying
     * map).
     */
    class Builder {
        private final List<ChannelSet> channels;
        public Builder() {
            channels = new ArrayList<>();
        }
        Builder(List<ChannelSet> channels) {
            this.channels = channels;
        }
        /**
         * Appends a new channel to the layout. The channel is mapped to one or more attribute ids.
         */
        public Builder append(ChannelSet set) {
            if (set.nameIds.size() < 1) {
                throw new IllegalArgumentException("Channel must be mapped to at least one id.");
            }
            channels.add(set);
            return this;
        }
        /**
         * Appends a new channel to the layout. The channel is mapped to a single attribute id.
         */
        public Builder append(NamedExpression attribute) {
            return append(new ChannelSet(Set.of(attribute.id()), attribute.dataType()));
        }