I was hitting this exception with `from * | limit 10` with the security rally track.

```
java.lang.IllegalArgumentException: Unknown writeable [org.elasticsearch.xpack.ql.type.EsField][InvalidMappedField]
	at org.elasticsearch.xpack.esql.io.stream.PlanNameRegistry.throwOnUnknownWritable(PlanNameRegistry.java:252) ~[?:?]
	at org.elasticsearch.xpack.esql.io.stream.PlanNameRegistry.getWriter(PlanNameRegistry.java:217) ~[?:?]
	at org.elasticsearch.xpack.esql.io.stream.PlanNameRegistry.getWriter(PlanNameRegistry.java:232) ~[?:?]
	at org.elasticsearch.xpack.esql.io.stream.PlanStreamOutput.writeNamed(PlanStreamOutput.java:76) ~[?:?]
	at org.elasticsearch.xpack.esql.io.stream.PlanNamedTypes.writeFieldAttribute(PlanNamedTypes.java:793) ~[?:?]
	at org.elasticsearch.xpack.esql.io.stream.PlanStreamOutput.writeNamed(PlanStreamOutput.java:78) ~[?:?]
	at org.elasticsearch.xpack.esql.io.stream.PlanStreamOutput.writeAttribute(PlanStreamOutput.java:61) ~[?:?]
	at org.elasticsearch.xpack.esql.io.stream.PlanNameRegistry$PlanWriter.write(PlanNameRegistry.java:46) ~[?:?]
	at org.elasticsearch.common.io.stream.StreamOutput.writeCollection(StreamOutput.java:1060) ~[elasticsearch-8.11.0-SNAPSHOT.jar:?]
	at org.elasticsearch.xpack.esql.io.stream.PlanNamedTypes.writeAttributes(PlanNamedTypes.java:764) ~[?:?]
	at org.elasticsearch.xpack.esql.io.stream.PlanNamedTypes.writeExchangeSinkExec(PlanNamedTypes.java:485) ~[?:?]
	at org.elasticsearch.xpack.esql.io.stream.PlanStreamOutput.writeNamed(PlanStreamOutput.java:78) ~[?:?]
	at org.elasticsearch.xpack.esql.io.stream.PlanStreamOutput.writePhysicalPlanNode(PlanStreamOutput.java:49) ~[?:?]
	at org.elasticsearch.xpack.esql.plugin.DataNodeRequest.writeTo(DataNodeRequest.java:72) ~[?:?]
```
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/io/stream/PlanNamedTypes.java
import org.elasticsearch.xpack.ql.type.UnsupportedEsField;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;
import static java.util.Map.entry;
import static org.elasticsearch.xpack.esql.io.stream.PlanNameRegistry.Entry.of;
import static org.elasticsearch.xpack.esql.io.stream.PlanNameRegistry.PlanReader.readerFromPlanReader;
import static org.elasticsearch.xpack.esql.io.stream.PlanNameRegistry.PlanWriter.writerFromPlanWriter;
/**
 * A utility class that consists solely of static methods that describe how to serialize and
 * deserialize QL and ESQL plan types.
 * <P>
 * All types that require to be serialized should have a pair of co-located `readFoo` and `writeFoo`
 * methods that deserialize and serialize respectively.
 * <P>
 * A type can be named or non-named. A named type has a name written to the stream before its
 * contents (similar to NamedWriteable), whereas a non-named type does not (similar to Writable).
 * Named types allow to determine specific deserialization implementations for more general types,
 * e.g. Literal, which is an Expression. Named types must have an entries in the namedTypeEntries
 * list.
 */
public final class PlanNamedTypes {
    private PlanNamedTypes() {}
    /**
     * Determines the writeable name of the give class. The simple class name is commonly used for
     * {@link NamedWriteable}s and is sufficient here too, but it could be almost anything else.
     */