### Elasticsearch Version

main @ 4de2ffa2bcf9eba0b8d09fb5f13c217598d025ee

### Installed Plugins

_No response_

### Java Version

openjdk version "17.0.8" 2023-07-18

### OS Version

Ubuntu 23.04

### Problem Description

- `MvExpandOperator` is [leaving behind unclosed input blocks](https://github.com/elastic/elasticsearch/blob/4de2ffa2bcf9eba0b8d09fb5f13c217598d025ee/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/operator/MvExpandOperatorTests.java#L137-L142). Should be closed by #100548
- `LimitOperator` is [leaving behind unclosed input blocks](https://github.com/elastic/elasticsearch/blob/4de2ffa2bcf9eba0b8d09fb5f13c217598d025ee/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/operator/LimitOperatorTests.java#L100-L105). #100465
- `FilterOperator` is [leaving behind unclosed input blocks](https://github.com/elastic/elasticsearch/blob/4de2ffa2bcf9eba0b8d09fb5f13c217598d025ee/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/operator/FilterOperatorTests.java#L128-L134). Should be closed by https://github.com/elastic/elasticsearch/pull/100465

### Steps to Reproduce

Remove the overridden `canLeak` implementation from `MvExpandOperatorTests`, `LimitOperatorTests` or `FilterOperatorTests` and run them.

### Logs (if relevant)

_No response_
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/LocalExecutionPlanner.java
sortByChannel = source.layout.get(a.id()).channel();
            } else {
                throw new EsqlIllegalArgumentException("order by expression must be an attribute");
            }
            return new TopNOperator.SortOrder(
                sortByChannel,
                order.direction().equals(Order.OrderDirection.ASC),
                order.nullsPosition().equals(Order.NullsPosition.FIRST)
            );
        }).toList();
        int limit;
        if (topNExec.limit() instanceof Literal literal) {
            limit = Integer.parseInt(literal.value().toString());
        } else {
            throw new EsqlIllegalArgumentException("limit only supported with literal values");
        }
        
        /*
         * The 2000 below is a hack to account for incoming size and to make
         * sure the estimated row size is never 0 which'd cause a divide by 0.
         * But we should replace this with passing the estimate into the real
         * topn and letting it actually measure the size of rows it produces.
         * That'll be more accurate. And we don't have a path for estimating
         * incoming rows. And we don't need one because we can estimate.
         */
        return source.with(
            new TopNOperatorFactory(
                limit,
                asList(elementTypes),
                asList(encoders),