### 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/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestUtils.java
lineNumber,
                                pos,
                                csvLine.substring(pos - 1)
                            )
                        );
                    }
                    mvValue.append("," + entry);
                } else {
                    mvCompressedEntries.add(entry);
                }
            }
            pos = 1 + (isLastElement ? csvLine.length() : commaPos);
        }
        return mvCompressedEntries.toArray(String[]::new);
    }
    public record ExpectedResults(List<String> columnNames, List<Type> columnTypes, List<List<Object>> values) {}
    public static ExpectedResults loadCsvSpecValues(String csv) {
        List<String> columnNames;
        List<Type> columnTypes;
        try (CsvListReader listReader = new CsvListReader(new StringReader(csv), CSV_SPEC_PREFERENCES)) {
            String[] header = listReader.getHeader(true);
            columnNames = new ArrayList<>(header.length);
            columnTypes = new ArrayList<>(header.length);
            for (String c : header) {
                String[] nameWithType = Strings.split(c, ":");
                if (nameWithType == null || nameWithType.length != 2) {
                    throw new IllegalArgumentException("Invalid CSV header " + c);
                }
                String typeName = nameWithType[1].trim();
                if (typeName.length() == 0) {