### 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
CombineProjections() {
            super(TransformDirection.UP);
        }
        @Override
        protected LogicalPlan rule(UnaryPlan plan) {
            LogicalPlan child = plan.child();
            if (plan instanceof Project project) {
                if (child instanceof Project p) {
                    
                    return p.withProjections(combineProjections(project.projections(), p.projections()));
                } else if (child instanceof Aggregate a) {
                    return new Aggregate(a.source(), a.child(), a.groupings(), combineProjections(project.projections(), a.aggregates()));
                }
            }
            
            if (plan instanceof Aggregate a) {
                if (child instanceof Project p) {
                    return new Aggregate(a.source(), p.child(), a.groupings(), combineProjections(a.aggregates(), p.projections()));
                }
            }
            return plan;
        }
        
        
        
        private List<NamedExpression> combineProjections(List<? extends NamedExpression> upper, List<? extends NamedExpression> lower) {
            
            AttributeMap.Builder<NamedExpression> aliasesBuilder = AttributeMap.builder();