### 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/optimizer/LogicalPlanOptimizer.java
SubstituteSurrogates() {
            super(TransformDirection.UP);
        }
        @Override
        protected LogicalPlan rule(Aggregate aggregate) {
            var aggs = aggregate.aggregates();
            List<NamedExpression> newAggs = new ArrayList<>(aggs.size());
            
            Map<AggregateFunction, Attribute> aggFuncToAttr = new HashMap<>();
            
            List<Alias> transientEval = new ArrayList<>();
            boolean changed = false;
            
            for (NamedExpression agg : aggs) {
                if (agg instanceof Alias a && a.child() instanceof AggregateFunction af && af instanceof SurrogateExpression == false) {
                    aggFuncToAttr.put(af, a.toAttribute());